@@ -1,5 +1,12 @@
This file documents the revision history for Perl extension Gitalist.
+0.002007 2011-02-19
+ - Add support for recursively searching for git repos (Dipesh Patel)
+ - Cleaned up model code in Gitalist::Git:: (Zachary Stevens)
+ - Improve POD mark-up, some typos (Lars Dɪᴇᴄᴋᴏᴡ 迪拉斯)
+ - Regenerated README and fixed tests for bootstrapped checkouts.
+ - Add Test::Exception dep.
+
0.002006 2010-10-17
- Added notes regarding slash encoding in Catalyst
- Fixed typo in core.css
@@ -1,20 +1,22 @@
Changes
gitalist.conf
inc/File/Copy/Recursive.pm
+inc/Module/AutoInstall.pm
inc/Module/Install.pm
-inc/Module/Install/WriteAll.pm
-inc/Module/Install/Include.pm
+inc/Module/Install/AuthorRequires.pm
+inc/Module/Install/AuthorTests.pm
+inc/Module/Install/AutoInstall.pm
inc/Module/Install/Base.pm
-inc/Module/Install/Metadata.pm
inc/Module/Install/Can.pm
-inc/Module/Install/Fetch.pm
-inc/Module/Install/External.pm
-inc/Module/Install/AutoInstall.pm
inc/Module/Install/Catalyst.pm
+inc/Module/Install/External.pm
+inc/Module/Install/Fetch.pm
+inc/Module/Install/Include.pm
inc/Module/Install/Makefile.pm
-inc/Module/Install/Win32.pm
+inc/Module/Install/Metadata.pm
inc/Module/Install/Scripts.pm
-inc/Module/AutoInstall.pm
+inc/Module/Install/Win32.pm
+inc/Module/Install/WriteAll.pm
lib/Gitalist.pm
lib/Gitalist/ActionRole/FilenameArgs.pm
lib/Gitalist/ContentMangler/Resolver.pm
@@ -32,8 +34,10 @@ lib/Gitalist/Controller/Root.pm
lib/Gitalist/Faq.pod
lib/Gitalist/Git/CollectionOfRepositories.pm
lib/Gitalist/Git/CollectionOfRepositories/FromDirectory.pm
+lib/Gitalist/Git/CollectionOfRepositories/FromDirectoryRecursive.pm
lib/Gitalist/Git/CollectionOfRepositories/FromListOfDirectories.pm
lib/Gitalist/Git/HasUtils.pm
+lib/Gitalist/Git/Head.pm
lib/Gitalist/Git/Object.pm
lib/Gitalist/Git/Object/Blob.pm
lib/Gitalist/Git/Object/Commit.pm
@@ -41,6 +45,7 @@ lib/Gitalist/Git/Object/HasTree.pm
lib/Gitalist/Git/Object/Tag.pm
lib/Gitalist/Git/Object/Tree.pm
lib/Gitalist/Git/Repository.pm
+lib/Gitalist/Git/Tag.pm
lib/Gitalist/Git/Types.pm
lib/Gitalist/Git/Util.pm
lib/Gitalist/Model/CollectionOfRepos.pm
@@ -68,6 +73,7 @@ root/_header_feeds.tt2
root/_log_pager.tt2
root/_refs.tt2
root/favicon.ico
+root/favicon_gif.ico
root/fragment/collectionofrepositories.tt2
root/fragment/ref/blame.tt2
root/fragment/ref/blob.tt2
@@ -159,8 +165,11 @@ script/gitalist_test.pl
t/00git_version.t
t/01app.t
t/02git_CollectionOfRepositories_FromDirectory.t
+t/02git_CollectionOfRepositories_FromDirectoryRecursive.t
+t/02git_head.t
t/02git_object.t
t/02git_Repository.t
+t/02git_tag.t
t/02git_util.t
t/03legacy_uri.t
t/app-mech-rootpage.t
@@ -207,6 +216,35 @@ t/lib/repositories/nodescription/objects/82/b5fee28277349b6d46beff5fdf6a7152347b
t/lib/repositories/nodescription/objects/90/62594aebb5df0de7fb92413f17a9eced196c22
t/lib/repositories/nodescription/objects/pack/.gitignore
t/lib/repositories/nodescription/refs/heads/master
+t/lib/repositories/recursive/barerecursive.git/config
+t/lib/repositories/recursive/barerecursive.git/description
+t/lib/repositories/recursive/barerecursive.git/HEAD
+t/lib/repositories/recursive/barerecursive.git/hooks/applypatch-msg.sample
+t/lib/repositories/recursive/barerecursive.git/hooks/commit-msg.sample
+t/lib/repositories/recursive/barerecursive.git/hooks/post-commit.sample
+t/lib/repositories/recursive/barerecursive.git/hooks/post-receive.sample
+t/lib/repositories/recursive/barerecursive.git/hooks/post-update.sample
+t/lib/repositories/recursive/barerecursive.git/hooks/pre-applypatch.sample
+t/lib/repositories/recursive/barerecursive.git/hooks/pre-commit.sample
+t/lib/repositories/recursive/barerecursive.git/hooks/pre-rebase.sample
+t/lib/repositories/recursive/barerecursive.git/hooks/prepare-commit-msg.sample
+t/lib/repositories/recursive/barerecursive.git/hooks/update.sample
+t/lib/repositories/recursive/barerecursive.git/info/exclude
+t/lib/repositories/recursive/goingdeeper/scratch.git/config
+t/lib/repositories/recursive/goingdeeper/scratch.git/description
+t/lib/repositories/recursive/goingdeeper/scratch.git/HEAD
+t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/applypatch-msg.sample
+t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/commit-msg.sample
+t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/post-commit.sample
+t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/post-receive.sample
+t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/post-update.sample
+t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/pre-applypatch.sample
+t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/pre-commit.sample
+t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/pre-rebase.sample
+t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/prepare-commit-msg.sample
+t/lib/repositories/recursive/goingdeeper/scratch.git/hooks/update.sample
+t/lib/repositories/recursive/goingdeeper/scratch.git/info/exclude
+t/lib/repositories/recursive/nothinginhere/emptyfile
t/lib/repositories/repo1/config
t/lib/repositories/repo1/description
t/lib/repositories/repo1/HEAD
@@ -12,4 +12,4 @@ Makefile\.old$
\.shipit$
script/bootstrap.pl
script/env
-
+local-lib5/
@@ -1,15 +1,17 @@
---
abstract: 'A modern git web viewer'
author:
+ - 'AND COPYRIGHT'
- 'Dan Brook <broq@cpan.org>'
build_requires:
ExtUtils::MakeMaker: 6.42
+ Test::Exception: 0.31
Test::More: 0.88
Test::utf8: 0.02
configure_requires:
ExtUtils::MakeMaker: 6.42
distribution_type: module
-generated_by: 'Module::Install version 0.91'
+generated_by: 'Module::Install version 1.00'
license: gpl2
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -22,7 +24,7 @@ no_index:
provides:
Gitalist:
file: lib/Gitalist.pm
- version: 0.002006
+ version: 0.002007
Gitalist::ActionRole::FilenameArgs:
file: lib/Gitalist/ActionRole/FilenameArgs.pm
Gitalist::ContentMangler::Resolver:
@@ -53,10 +55,14 @@ provides:
file: lib/Gitalist/Git/CollectionOfRepositories.pm
Gitalist::Git::CollectionOfRepositories::FromDirectory:
file: lib/Gitalist/Git/CollectionOfRepositories/FromDirectory.pm
+ Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive:
+ file: lib/Gitalist/Git/CollectionOfRepositories/FromDirectoryRecursive.pm
Gitalist::Git::CollectionOfRepositories::FromListOfDirectories:
file: lib/Gitalist/Git/CollectionOfRepositories/FromListOfDirectories.pm
Gitalist::Git::HasUtils:
file: lib/Gitalist/Git/HasUtils.pm
+ Gitalist::Git::Head:
+ file: lib/Gitalist/Git/Head.pm
Gitalist::Git::Object:
file: lib/Gitalist/Git/Object.pm
Gitalist::Git::Object::Blob:
@@ -71,6 +77,8 @@ provides:
file: lib/Gitalist/Git/Object/Tree.pm
Gitalist::Git::Repository:
file: lib/Gitalist/Git/Repository.pm
+ Gitalist::Git::Tag:
+ file: lib/Gitalist/Git/Tag.pm
Gitalist::Git::Types:
file: lib/Gitalist/Git/Types.pm
Gitalist::Git::Util:
@@ -148,4 +156,4 @@ resources:
bugtracker: http://rt.cpan.org/Public/Dist/Display.html?Name=Gitalist
license: http://opensource.org/licenses/gpl-2.0.php
repository: git://git.shadowcat.co.uk/catagits/Gitalist.git
-version: 0.002006
+version: 0.002007
@@ -106,8 +106,9 @@ requires 'Sys::Hostname';
requires_external_bin 'git';
-test_requires 'Test::More' => '0.88';
-test_requires 'Test::utf8' => '0.02';
+test_requires 'Test::More' => '0.88';
+test_requires 'Test::utf8' => '0.02';
+test_requires 'Test::Exception' => '0.31';
resources bugtracker => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Gitalist';
resources repository => 'git://git.shadowcat.co.uk/catagits/Gitalist.git';
@@ -6,7 +6,7 @@ SYNOPSIS
INSTALL
As Gitalist follows the usual Perl module format the usual approach for
- installation should work e.g.
+ installation should work, e.g.:
perl Makefile.PL
make
@@ -17,20 +17,20 @@ INSTALL
cpan -i Gitalist
- You can also check gitalist out from git and run it, in this case you'll
- additionally need the author modules, but no configuration will be
- needed as it will default to looking for repositories the directory
- above the checkout.
+ You can also check Gitalist out from its git repository and run it, in
+ this case you'll additionally need the author modules, but no
+ configuration will be needed as it will default to looking for
+ repositories the directory above the checkout.
DESCRIPTION
- Gitalist is a web frontend for git repositories based on gitweb.cgi and
- backed by Catalyst.
+ Gitalist is a web frontend for git repositories based on <gitweb.cgi>
+ and backed by Catalyst.
History
- This project started off as an attempt to port gitweb.cgi to a Catalyst
- app in a piecemeal fashion. As it turns out, thanks largely to Florian
- Ragwitz's earlier effort, it was easier to use gitweb.cgi as a template
- for building a new Catalyst application.
+ This project started off as an attempt to port *gitweb.cgi* to a
+ Catalyst app in a piecemeal fashion. As it turns out, thanks largely to
+ Florian Ragwitz's earlier effort, it was easier to use *gitweb.cgi* as a
+ template for building a new Catalyst application.
GETTING GITALIST
You can install Gitalist from CPAN in the usual way:
@@ -43,8 +43,9 @@ GETTING GITALIST
git://git.shadowcat.co.uk/catagits/Gitalist.git
- Gitalist is also mirrored to github, and a number of people have active
- forks with branches and/or new features in the master branch.
+ Gitalist is also mirrored to GitHub at
+ <https://github.com/broquaint/Gitalist>, and a number of people have
+ active forks with branches and/or new features in the master branch.
BOOTSTRAPPING
As of 0.002001 Gitalist can now be bootstrapped to run out of its own
@@ -53,9 +54,9 @@ BOOTSTRAPPING
path with CPAN they are installed under the Gitalist directory.
To do this clone Gitalist from the Shadowcat repository mentioned above
- or grab a snapshot from broquaint's github repository:
+ or grab a snapshot from broquaint's GitHub repository:
- http://github.com/broquaint/Gitalist/downloads
+ https://github.com/broquaint/Gitalist/downloads
With the source acquired and unpacked run the following from within the
Gitalist directory:
@@ -65,7 +66,7 @@ BOOTSTRAPPING
This will install the necessary modules for the build process which in
turn installs the prerequisites locally.
- *NB* The relevant bootstrap scripts aren't available in the CPAN dist as
+ NB: The relevant bootstrap scripts aren't available in the CPAN dist as
the bootstrap scripts should not be installed.
INITIAL CONFIGURATION
@@ -95,8 +96,8 @@ INITIAL CONFIGURATION
cp `perl -Ilib -MGitalist -e'print Gitalist->path_to("gitalist.conf")'` gitalist.conf
- You can then edit this confg, adding a repo_dir path and customising
- other settings as desired.
+ You can then edit this configuration, adding a "repo_dir" path and
+ customising other settings as desired.
You can then start the Gitalist demo server by setting
"GITALIST_CONFIG". For example:
@@ -121,7 +122,7 @@ RUNNING
than using the single threaded developement server.
The recommended deployment method for Gitalist is FastCGI, although
- Gitalist can also be run under mod_perl or as pure perl with
+ Gitalist can also be run under <mod_perl> or as pure Perl with
Catalyst::Engine::PreFork.
Assuming that you have installed Gitalist's dependencies into a
@@ -137,42 +138,48 @@ RUNNING
http://example.gitalist.com
FASTCGI
- Running Gitalist in FastCGI mode requires a webserver with FastCGI
- support (such as apache with mod_fcgi or fcgid). Below is a sample
- configuration using Apache2 with fcgid in a dynamic configuration
- (as opposed to static or standalone mode). More information on these modes and
- their configuration can be found at
- http://search.cpan.org/~bobtfish/Catalyst-Runtime-5.80025/lib/Catalyst/Engine/FastCGI.pm#Standalone_server_mode
- In Apache's mime.conf, add AddHandler fcgid-script .fcgi (or AddHandler fastcgi-script .fcgi for mod_fcgi)
-
- And a quick VirtualHost configuration:
-
- <VirtualHost *:80>
- ServerName gitalist.yourdomain.com
- DocumentRoot /path/to/gitalist.fcgi
- <Directory "/path/to/gitalist.fcgi">
+ Running Gitalist in FastCGI mode requires a webserver with FastCGI
+ support (such as apache with <mod_fcgi> or <mod_fcgid>). Below is a
+ sample configuration using Apache2 with mod_fcgid in a dynamic
+ configuration (as opposed to static or standalone mode). More
+ information on these modes and their configuration can be found at
+ "Standalone server mode" in Catalyst::Engine::FastCGI.
+
+ In Apache's mime.conf, add "AddHandler fcgid-script .fcgi" (or
+ "AddHandler fastcgi-script .fcgi" for mod_fcgi).
+
+ And a quick VirtualHost configuration:
+
+ <VirtualHost *:80>
+ ServerName gitalist.yourdomain.com
+ DocumentRoot /path/to/gitalist.fcgi
+ <Directory "/path/to/gitalist.fcgi">
AllowOverride all
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
- </Directory>
+ </Directory>
# Tell Apache this is a FastCGI application
<Files gitalist.fcgi>
#change the below to fastcgi-script if using mod_fcgi
SetHandler fcgid-script
</Files>
- </VirtualHost>
-
- Now to access your gitalist instance, you'll go to gitalist.yourdomain.com/gitalist.fcgi/
- (DO NOT FORGET THAT TRAILING /). If you'd like a different URL, of course, you'll likely want to use
- mod_rewrite or equivalent
-
- If you find the need to do some troubleshooting, you can call http://url_to_gitalist.fcgi?dump_info=1
- and/or add export GITALIST_DEBUG=1 to the top of you gitalist.fcgi file (just below the shebang line).
-
- Also, note that Apache will refuse %2F in Gitalist URL's unless configured otherwise. Make sure
- "AllowEncodedSlashes On" is in your httpd.conf file in order for this to run smoothly.
+ </VirtualHost>
+
+ Now to access your Gitalist instance, you'll go to
+ "gitalist.yourdomain.com/gitalist.fcgi/" (do not forget that trailing
+ "/"). If you'd like a different URL, of course, you'll likely want to
+ use <mod_rewrite> or equivalent.
+
+ If you find the need to do some troubleshooting, you can call
+ "http://url_to_gitalist.fcgi?dump_info=1" and/or add export
+ "GITALIST_DEBUG=1" to the top of your gitalist.fcgi file (just below the
+ shebang line).
+
+ Also, note that Apache will refuse %2F in Gitalist URLs unless
+ configured otherwise. Make sure "AllowEncodedSlashes On" is in your
+ httpd.conf file in order for this to run smoothly.
CONTRIBUTING
Patches are welcome, please feel free to fork on github and send pull
@@ -194,16 +201,16 @@ SEE ALSO
AUTHORS AND COPYRIGHT
Catalyst application:
- (C) 2009 Venda Ltd and Dan Brook <broq@cpan.org>
- (C) 2009, Tom Doran <bobtfish@bobtfish.net>
- (C) 2009, Zac Stevens <zts@cryptocracy.com>
+ © 2009 Venda Ltd and Dan Brook <broq@cpan.org>
+ © 2009, Tom Doran <bobtfish@bobtfish.net>
+ © 2009, Zac Stevens <zts@cryptocracy.com>
Original gitweb.cgi from which this was derived:
- (C) 2005-2006, Kay Sievers <kay.sievers@vrfy.org>
- (C) 2005, Christian Gierke
+ © 2005-2006, Kay Sievers <kay.sievers@vrfy.org>
+ © 2005, Christian Gierke
Model based on http://github.com/rafl/gitweb
- (C) 2008, Florian Ragwitz
+ © 2008, Florian Ragwitz
LICENSE
Licensed under GNU GPL v2
@@ -253,6 +253,8 @@ sub import {
# import to main::
no strict 'refs';
*{'main::WriteMakefile'} = \&Write if caller(0) eq 'main';
+
+ return (@Existing, @Missing);
}
sub _running_under {
@@ -672,7 +674,20 @@ sub _load {
sub _load_cpan {
return if $CPAN::VERSION and $CPAN::Config and not @_;
require CPAN;
- if ( $CPAN::HandleConfig::VERSION ) {
+
+ # CPAN-1.82+ adds CPAN::Config::AUTOLOAD to redirect to
+ # CPAN::HandleConfig->load. CPAN reports that the redirection
+ # is deprecated in a warning printed at the user.
+
+ # CPAN-1.81 expects CPAN::HandleConfig->load, does not have
+ # $CPAN::HandleConfig::VERSION but cannot handle
+ # CPAN::Config->load
+
+ # Which "versions expect CPAN::Config->load?
+
+ if ( $CPAN::HandleConfig::VERSION
+ || CPAN::HandleConfig->can('load')
+ ) {
# Newer versions of CPAN have a HandleConfig module
CPAN::HandleConfig->load;
} else {
@@ -802,4 +817,4 @@ END_MAKE
__END__
-#line 1056
+#line 1071
@@ -0,0 +1,38 @@
+#line 1
+use strict;
+use warnings;
+
+package Module::Install::AuthorRequires;
+
+use base 'Module::Install::Base';
+
+# cargo cult
+BEGIN {
+ our $VERSION = '0.02';
+ our $ISCORE = 1;
+}
+
+sub author_requires {
+ my $self = shift;
+
+ return $self->{values}->{author_requires}
+ unless @_;
+
+ my @added;
+ while (@_) {
+ my $mod = shift or last;
+ my $version = shift || 0;
+ push @added, [$mod => $version];
+ }
+
+ push @{ $self->{values}->{author_requires} }, @added;
+ $self->admin->author_requires(@added);
+
+ return map { @$_ } @added;
+}
+
+1;
+
+__END__
+
+#line 92
@@ -0,0 +1,59 @@
+#line 1
+package Module::Install::AuthorTests;
+
+use 5.005;
+use strict;
+use Module::Install::Base;
+use Carp ();
+
+#line 16
+
+use vars qw{$VERSION $ISCORE @ISA};
+BEGIN {
+ $VERSION = '0.002';
+ $ISCORE = 1;
+ @ISA = qw{Module::Install::Base};
+}
+
+#line 42
+
+sub author_tests {
+ my ($self, @dirs) = @_;
+ _add_author_tests($self, \@dirs, 0);
+}
+
+#line 56
+
+sub recursive_author_tests {
+ my ($self, @dirs) = @_;
+ _add_author_tests($self, \@dirs, 1);
+}
+
+sub _wanted {
+ my $href = shift;
+ sub { /\.t$/ and -f $_ and $href->{$File::Find::dir} = 1 }
+}
+
+sub _add_author_tests {
+ my ($self, $dirs, $recurse) = @_;
+ return unless $Module::Install::AUTHOR;
+
+ my @tests = $self->tests ? (split / /, $self->tests) : 't/*.t';
+
+ # XXX: pick a default, later -- rjbs, 2008-02-24
+ my @dirs = @$dirs ? @$dirs : Carp::confess "no dirs given to author_tests";
+ @dirs = grep { -d } @dirs;
+
+ if ($recurse) {
+ require File::Find;
+ my %test_dir;
+ File::Find::find(_wanted(\%test_dir), @dirs);
+ $self->tests( join ' ', @tests, map { "$_/*.t" } sort keys %test_dir );
+ } else {
+ $self->tests( join ' ', @tests, map { "$_/*.t" } sort @dirs );
+ }
+}
+
+#line 107
+
+1;
@@ -6,7 +6,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.91';
+ $VERSION = '1.00';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
@@ -37,12 +37,33 @@ sub auto_install {
$self->include('Module::AutoInstall');
require Module::AutoInstall;
- Module::AutoInstall->import(
+ my @features_require = Module::AutoInstall->import(
(@config ? (-config => \@config) : ()),
(@core ? (-core => \@core) : ()),
$self->features,
);
+ my %seen;
+ my @requires = map @$_, map @$_, grep ref, $self->requires;
+ while (my ($mod, $ver) = splice(@requires, 0, 2)) {
+ $seen{$mod}{$ver}++;
+ }
+ my @build_requires = map @$_, map @$_, grep ref, $self->build_requires;
+ while (my ($mod, $ver) = splice(@build_requires, 0, 2)) {
+ $seen{$mod}{$ver}++;
+ }
+ my @configure_requires = map @$_, map @$_, grep ref, $self->configure_requires;
+ while (my ($mod, $ver) = splice(@configure_requires, 0, 2)) {
+ $seen{$mod}{$ver}++;
+ }
+
+ my @deduped;
+ while (my ($mod, $ver) = splice(@features_require, 0, 2)) {
+ push @deduped, $mod => $ver unless $seen{$mod}{$ver}++;
+ }
+
+ $self->requires(@deduped);
+
$self->makemaker_args( Module::AutoInstall::_make_args() );
my $class = ref($self);
@@ -4,7 +4,7 @@ package Module::Install::Base;
use strict 'vars';
use vars qw{$VERSION};
BEGIN {
- $VERSION = '0.91';
+ $VERSION = '1.00';
}
# Suspend handler for "redefined" warnings
@@ -51,13 +51,18 @@ sub admin {
#line 106
sub is_admin {
- $_[0]->admin->VERSION;
+ ! $_[0]->admin->isa('Module::Install::Base::FakeAdmin');
}
sub DESTROY {}
package Module::Install::Base::FakeAdmin;
+use vars qw{$VERSION};
+BEGIN {
+ $VERSION = $Module::Install::Base::VERSION;
+}
+
my $fake;
sub new {
@@ -75,4 +80,4 @@ BEGIN {
1;
-#line 154
+#line 159
@@ -9,7 +9,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.91';
+ $VERSION = '1.00';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
@@ -9,25 +9,35 @@ require Module::Install::Base;
use File::Find;
use FindBin;
-use File::Copy::Recursive 'rcopy';
+use File::Copy::Recursive;
use File::Spec ();
+use Getopt::Long ();
+use Data::Dumper;
my $SAFETY = 0;
our @IGNORE =
qw/Build Build.PL Changes MANIFEST META.yml Makefile.PL Makefile README
- _build blib lib script t inc \.svn \.git _darcs \.bzr \.hg/;
+ _build blib lib script t inc .*\.svn \.git _darcs \.bzr \.hg
+ debian build-stamp install-stamp configure-stamp/;
our @CLASSES = ();
our $ENGINE = 'CGI';
-our $CORE = 0;
-our $MULTIARCH = 0;
our $SCRIPT = '';
our $USAGE = '';
+our %PAROPTS = ();
-#line 42
+#line 57
sub catalyst {
my $self = shift;
+
+ if($Module::Install::AUTHOR) {
+ $self->admin->copy_package(
+ 'File::Copy::Recursive',
+ $INC{"File/Copy/Recursive.pm"},
+ );
+ }
+
print <<EOF;
*** Module::Install::Catalyst
EOF
@@ -38,7 +48,7 @@ EOF
EOF
}
-#line 58
+#line 85
sub catalyst_files {
my $self = shift;
@@ -58,25 +68,25 @@ sub catalyst_files {
my @path = split '-', $self->name;
for my $orig (@files) {
my $path = File::Spec->catdir( 'blib', 'lib', @path, $orig );
- rcopy( $orig, $path );
+ File::Copy::Recursive::rcopy( $orig, $path );
}
}
-#line 84
+#line 113
sub catalyst_ignore_all {
my ( $self, $ignore ) = @_;
@IGNORE = @$ignore;
}
-#line 93
+#line 124
sub catalyst_ignore {
my ( $self, @ignore ) = @_;
push @IGNORE, @ignore;
}
-#line 102
+#line 133
# Workaround for a namespace conflict
sub catalyst_par {
@@ -89,51 +99,75 @@ sub catalyst_par {
$usage =~ s/"/\\"/g;
my $class_string = join "', '", @CLASSES;
$class_string = "'$class_string'" if $class_string;
+ local $Data::Dumper::Indent = 0;
+ local $Data::Dumper::Terse = 1;
+ local $Data::Dumper::Pad = ' ';
+ my $paropts_string = Dumper(\%PAROPTS) || "{ }";
$self->postamble(<<EOF);
catalyst_par :: all
-\t\$(NOECHO) \$(PERL) -Ilib -Minc::Module::Install -MModule::Install::Catalyst -e"Catalyst::Module::Install::_catalyst_par( '$par', '$name', { CLASSES => [$class_string], CORE => $CORE, ENGINE => '$ENGINE', MULTIARCH => $MULTIARCH, SCRIPT => '$SCRIPT', USAGE => q#$usage# } )"
+\t\$(NOECHO) \$(PERL) -Ilib -Minc::Module::Install -MModule::Install::Catalyst -e"Catalyst::Module::Install::_catalyst_par( '$par', '$name', { CLASSES => [$class_string], PAROPTS => $paropts_string, ENGINE => '$ENGINE', SCRIPT => '$SCRIPT', USAGE => q#$usage# } )"
EOF
print <<EOF;
Please run "make catalyst_par" to create the PAR package!
EOF
}
-#line 126
+#line 161
sub catalyst_par_core {
my ( $self, $core ) = @_;
- $core ? ( $CORE = $core ) : $CORE++;
+ $core ? ( $PAROPTS{'B'} = $core ) : $PAROPTS{'B'}++;
}
-#line 135
+#line 170
sub catalyst_par_classes {
my ( $self, @classes ) = @_;
push @CLASSES, @classes;
}
-#line 144
+#line 179
sub catalyst_par_engine {
my ( $self, $engine ) = @_;
$ENGINE = $engine;
}
-#line 153
+#line 188
sub catalyst_par_multiarch {
my ( $self, $multiarch ) = @_;
- $multiarch ? ( $MULTIARCH = $multiarch ) : $MULTIARCH++;
+ $multiarch ? ( $PAROPTS{'m'} = $multiarch ) : $PAROPTS{'m'}++;
}
-#line 162
+#line 221
+
+sub catalyst_par_options {
+ my ( $self, $optstring ) = @_;
+ eval "use PAR::Packer ()";
+ if ($@) {
+ warn "WARNING: catalyst_par_options ignored - you need PAR::Packer\n"
+ }
+ else {
+ my $p = Getopt::Long::Parser->new(config => ['no_ignore_case']);
+ my %o;
+ require Text::ParseWords;
+ {
+ local @ARGV = Text::ParseWords::shellwords($optstring);
+ $p->getoptions(\%o, PAR::Packer->options);
+ }
+ %PAROPTS = ( %PAROPTS, %o);
+ }
+}
+
+#line 243
sub catalyst_par_script {
my ( $self, $script ) = @_;
$SCRIPT = $script;
}
-#line 171
+#line 252
sub catalyst_par_usage {
my ( $self, $usage ) = @_;
@@ -154,8 +188,7 @@ sub _catalyst_par {
my $CLASSES = $opts->{CLASSES} || [];
my $USAGE = $opts->{USAGE};
my $SCRIPT = $opts->{SCRIPT};
- my $MULTIARCH = $opts->{MULTIARCH};
- my $CORE = $opts->{CORE};
+ my $PAROPTS = $opts->{PAROPTS};
my $name = $class_name;
$name =~ s/::/_/g;
@@ -261,14 +294,16 @@ EOF
open my $olderr, '>&STDERR';
open STDERR, '>', File::Spec->devnull;
my %opt = (
+ %{$PAROPTS},
+ # take user defined options first and override them with harcoded defaults
'x' => 1,
'n' => 0,
'o' => $par,
- 'a' => [ grep( !/par.pl/, glob '.' ) ],
'p' => 1,
- 'B' => $CORE,
- 'm' => $MULTIARCH
);
+ # do not replace the whole $opt{'a'} array; just push required default value
+ push @{$opt{'a'}}, grep( !/par.pl/, glob '.' );
+
App::Packer::PAR->new(
frontend => 'Module::ScanDeps',
backend => 'PAR::Packer',
@@ -285,6 +320,6 @@ EOF
return 1;
}
-#line 332
+#line 414
1;
@@ -8,7 +8,7 @@ use Module::Install::Base ();
use vars qw{$VERSION $ISCORE @ISA};
BEGIN {
- $VERSION = '0.91';
+ $VERSION = '1.00';
$ISCORE = 1;
@ISA = qw{Module::Install::Base};
}
@@ -6,7 +6,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.91';
+ $VERSION = '1.00';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
@@ -6,7 +6,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.91';
+ $VERSION = '1.00';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
@@ -4,10 +4,11 @@ package Module::Install::Makefile;
use strict 'vars';
use ExtUtils::MakeMaker ();
use Module::Install::Base ();
+use Fcntl qw/:flock :seek/;
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.91';
+ $VERSION = '1.00';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
@@ -25,8 +26,8 @@ sub prompt {
die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])";
}
- # In automated testing, always use defaults
- if ( $ENV{AUTOMATED_TESTING} and ! $ENV{PERL_MM_USE_DEFAULT} ) {
+ # In automated testing or non-interactive session, always use defaults
+ if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) {
local $ENV{PERL_MM_USE_DEFAULT} = 1;
goto &ExtUtils::MakeMaker::prompt;
} else {
@@ -34,21 +35,112 @@ sub prompt {
}
}
+# Store a cleaned up version of the MakeMaker version,
+# since we need to behave differently in a variety of
+# ways based on the MM version.
+my $makemaker = eval $ExtUtils::MakeMaker::VERSION;
+
+# If we are passed a param, do a "newer than" comparison.
+# Otherwise, just return the MakeMaker version.
+sub makemaker {
+ ( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0
+}
+
+# Ripped from ExtUtils::MakeMaker 6.56, and slightly modified
+# as we only need to know here whether the attribute is an array
+# or a hash or something else (which may or may not be appendable).
+my %makemaker_argtype = (
+ C => 'ARRAY',
+ CONFIG => 'ARRAY',
+# CONFIGURE => 'CODE', # ignore
+ DIR => 'ARRAY',
+ DL_FUNCS => 'HASH',
+ DL_VARS => 'ARRAY',
+ EXCLUDE_EXT => 'ARRAY',
+ EXE_FILES => 'ARRAY',
+ FUNCLIST => 'ARRAY',
+ H => 'ARRAY',
+ IMPORTS => 'HASH',
+ INCLUDE_EXT => 'ARRAY',
+ LIBS => 'ARRAY', # ignore ''
+ MAN1PODS => 'HASH',
+ MAN3PODS => 'HASH',
+ META_ADD => 'HASH',
+ META_MERGE => 'HASH',
+ PL_FILES => 'HASH',
+ PM => 'HASH',
+ PMLIBDIRS => 'ARRAY',
+ PMLIBPARENTDIRS => 'ARRAY',
+ PREREQ_PM => 'HASH',
+ CONFIGURE_REQUIRES => 'HASH',
+ SKIP => 'ARRAY',
+ TYPEMAPS => 'ARRAY',
+ XS => 'HASH',
+# VERSION => ['version',''], # ignore
+# _KEEP_AFTER_FLUSH => '',
+
+ clean => 'HASH',
+ depend => 'HASH',
+ dist => 'HASH',
+ dynamic_lib=> 'HASH',
+ linkext => 'HASH',
+ macro => 'HASH',
+ postamble => 'HASH',
+ realclean => 'HASH',
+ test => 'HASH',
+ tool_autosplit => 'HASH',
+
+ # special cases where you can use makemaker_append
+ CCFLAGS => 'APPENDABLE',
+ DEFINE => 'APPENDABLE',
+ INC => 'APPENDABLE',
+ LDDLFLAGS => 'APPENDABLE',
+ LDFROM => 'APPENDABLE',
+);
+
sub makemaker_args {
- my $self = shift;
+ my ($self, %new_args) = @_;
my $args = ( $self->{makemaker_args} ||= {} );
- %$args = ( %$args, @_ );
+ foreach my $key (keys %new_args) {
+ if ($makemaker_argtype{$key}) {
+ if ($makemaker_argtype{$key} eq 'ARRAY') {
+ $args->{$key} = [] unless defined $args->{$key};
+ unless (ref $args->{$key} eq 'ARRAY') {
+ $args->{$key} = [$args->{$key}]
+ }
+ push @{$args->{$key}},
+ ref $new_args{$key} eq 'ARRAY'
+ ? @{$new_args{$key}}
+ : $new_args{$key};
+ }
+ elsif ($makemaker_argtype{$key} eq 'HASH') {
+ $args->{$key} = {} unless defined $args->{$key};
+ foreach my $skey (keys %{ $new_args{$key} }) {
+ $args->{$key}{$skey} = $new_args{$key}{$skey};
+ }
+ }
+ elsif ($makemaker_argtype{$key} eq 'APPENDABLE') {
+ $self->makemaker_append($key => $new_args{$key});
+ }
+ }
+ else {
+ if (defined $args->{$key}) {
+ warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n};
+ }
+ $args->{$key} = $new_args{$key};
+ }
+ }
return $args;
}
# For mm args that take multiple space-seperated args,
# append an argument to the current list.
sub makemaker_append {
- my $self = sShift;
+ my $self = shift;
my $name = shift;
my $args = $self->makemaker_args;
- $args->{name} = defined $args->{$name}
- ? join( ' ', $args->{name}, @_ )
+ $args->{$name} = defined $args->{$name}
+ ? join( ' ', $args->{$name}, @_ )
: join( ' ', @_ );
}
@@ -89,25 +181,22 @@ sub inc {
$self->makemaker_args( INC => shift );
}
-my %test_dir = ();
-
sub _wanted_t {
- /\.t$/ and -f $_ and $test_dir{$File::Find::dir} = 1;
}
sub tests_recursive {
my $self = shift;
- if ( $self->tests ) {
- die "tests_recursive will not work if tests are already defined";
- }
my $dir = shift || 't';
unless ( -d $dir ) {
die "tests_recursive dir '$dir' does not exist";
}
- %test_dir = ();
+ my %tests = map { $_ => 1 } split / /, ($self->tests || '');
require File::Find;
- File::Find::find( \&_wanted_t, $dir );
- $self->tests( join ' ', map { "$_/*.t" } sort keys %test_dir );
+ File::Find::find(
+ sub { /\.t$/ and -f $_ and $tests{"$File::Find::dir/*.t"} = 1 },
+ $dir
+ );
+ $self->tests( join ' ', sort keys %tests );
}
sub write {
@@ -130,12 +219,13 @@ sub write {
# an underscore, even though its own version may contain one!
# Hence the funny regexp to get rid of it. See RT #35800
# for details.
- $self->build_requires( 'ExtUtils::MakeMaker' => $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/ );
- $self->configure_requires( 'ExtUtils::MakeMaker' => $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/ );
+ my $v = $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/;
+ $self->build_requires( 'ExtUtils::MakeMaker' => $v );
+ $self->configure_requires( 'ExtUtils::MakeMaker' => $v );
} else {
# Allow legacy-compatibility with 5.005 by depending on the
# most recent EU:MM that supported 5.005.
- $self->build_requires( 'ExtUtils::MakeMaker' => 6.42 );
+ $self->build_requires( 'ExtUtils::MakeMaker' => 6.42 );
$self->configure_requires( 'ExtUtils::MakeMaker' => 6.42 );
}
@@ -143,59 +233,115 @@ sub write {
my $args = $self->makemaker_args;
$args->{DISTNAME} = $self->name;
$args->{NAME} = $self->module_name || $self->name;
- $args->{VERSION} = $self->version;
$args->{NAME} =~ s/-/::/g;
+ $args->{VERSION} = $self->version or die <<'EOT';
+ERROR: Can't determine distribution version. Please specify it
+explicitly via 'version' in Makefile.PL, or set a valid $VERSION
+in a module, and provide its file path via 'version_from' (or
+'all_from' if you prefer) in Makefile.PL.
+EOT
+
+ $DB::single = 1;
if ( $self->tests ) {
- $args->{test} = { TESTS => $self->tests };
+ my @tests = split ' ', $self->tests;
+ my %seen;
+ $args->{test} = {
+ TESTS => (join ' ', grep {!$seen{$_}++} @tests),
+ };
+ } elsif ( $Module::Install::ExtraTests::use_extratests ) {
+ # Module::Install::ExtraTests doesn't set $self->tests and does its own tests via harness.
+ # So, just ignore our xt tests here.
+ } elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) {
+ $args->{test} = {
+ TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ),
+ };
}
if ( $] >= 5.005 ) {
$args->{ABSTRACT} = $self->abstract;
- $args->{AUTHOR} = $self->author;
+ $args->{AUTHOR} = join ', ', @{$self->author || []};
}
- if ( eval($ExtUtils::MakeMaker::VERSION) >= 6.10 ) {
- $args->{NO_META} = 1;
+ if ( $self->makemaker(6.10) ) {
+ $args->{NO_META} = 1;
+ #$args->{NO_MYMETA} = 1;
}
- if ( eval($ExtUtils::MakeMaker::VERSION) > 6.17 and $self->sign ) {
+ if ( $self->makemaker(6.17) and $self->sign ) {
$args->{SIGN} = 1;
}
unless ( $self->is_admin ) {
delete $args->{SIGN};
}
+ if ( $self->makemaker(6.31) and $self->license ) {
+ $args->{LICENSE} = $self->license;
+ }
- # Merge both kinds of requires into prereq_pm
my $prereq = ($args->{PREREQ_PM} ||= {});
%$prereq = ( %$prereq,
- map { @$_ }
+ map { @$_ } # flatten [module => version]
map { @$_ }
grep $_,
- ($self->configure_requires, $self->build_requires, $self->requires)
+ ($self->requires)
);
# Remove any reference to perl, PREREQ_PM doesn't support it
delete $args->{PREREQ_PM}->{perl};
- # merge both kinds of requires into prereq_pm
- my $subdirs = ($args->{DIR} ||= []);
+ # Merge both kinds of requires into BUILD_REQUIRES
+ my $build_prereq = ($args->{BUILD_REQUIRES} ||= {});
+ %$build_prereq = ( %$build_prereq,
+ map { @$_ } # flatten [module => version]
+ map { @$_ }
+ grep $_,
+ ($self->configure_requires, $self->build_requires)
+ );
+
+ # Remove any reference to perl, BUILD_REQUIRES doesn't support it
+ delete $args->{BUILD_REQUIRES}->{perl};
+
+ # Delete bundled dists from prereq_pm, add it to Makefile DIR
+ my $subdirs = ($args->{DIR} || []);
if ($self->bundles) {
+ my %processed;
foreach my $bundle (@{ $self->bundles }) {
- my ($file, $dir) = @$bundle;
- push @$subdirs, $dir if -d $dir;
- delete $prereq->{$file};
+ my ($mod_name, $dist_dir) = @$bundle;
+ delete $prereq->{$mod_name};
+ $dist_dir = File::Basename::basename($dist_dir); # dir for building this module
+ if (not exists $processed{$dist_dir}) {
+ if (-d $dist_dir) {
+ # List as sub-directory to be processed by make
+ push @$subdirs, $dist_dir;
+ }
+ # Else do nothing: the module is already present on the system
+ $processed{$dist_dir} = undef;
+ }
}
}
+ unless ( $self->makemaker('6.55_03') ) {
+ %$prereq = (%$prereq,%$build_prereq);
+ delete $args->{BUILD_REQUIRES};
+ }
+
if ( my $perl_version = $self->perl_version ) {
eval "use $perl_version; 1"
or die "ERROR: perl: Version $] is installed, "
. "but we need version >= $perl_version";
+
+ if ( $self->makemaker(6.48) ) {
+ $args->{MIN_PERL_VERSION} = $perl_version;
+ }
}
- $args->{INSTALLDIRS} = $self->installdirs;
+ if ($self->installdirs) {
+ warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS};
+ $args->{INSTALLDIRS} = $self->installdirs;
+ }
- my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_})} keys %$args;
+ my %args = map {
+ ( $_ => $args->{$_} ) } grep {defined($args->{$_} )
+ } keys %$args;
my $user_preop = delete $args{dist}->{PREOP};
- if (my $preop = $self->admin->preop($user_preop)) {
+ if ( my $preop = $self->admin->preop($user_preop) ) {
foreach my $key ( keys %$preop ) {
$args{dist}->{$key} = $preop->{$key};
}
@@ -219,9 +365,9 @@ sub fix_up_makefile {
. ($self->postamble || '');
local *MAKEFILE;
- open MAKEFILE, "< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
+ open MAKEFILE, "+< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
+ eval { flock MAKEFILE, LOCK_EX };
my $makefile = do { local $/; <MAKEFILE> };
- close MAKEFILE or die $!;
$makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /;
$makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g;
@@ -241,7 +387,8 @@ sub fix_up_makefile {
# XXX - This is currently unused; not sure if it breaks other MM-users
# $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg;
- open MAKEFILE, "> $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
+ seek MAKEFILE, 0, SEEK_SET;
+ truncate MAKEFILE, 0;
print MAKEFILE "$preamble$makefile$postamble" or die $!;
close MAKEFILE or die $!;
@@ -265,4 +412,4 @@ sub postamble {
__END__
-#line 394
+#line 541
@@ -6,7 +6,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.91';
+ $VERSION = '1.00';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
@@ -19,7 +19,6 @@ my @scalar_keys = qw{
name
module_name
abstract
- author
version
distribution_type
tests
@@ -43,8 +42,11 @@ my @resource_keys = qw{
my @array_keys = qw{
keywords
+ author
};
+*authors = \&author;
+
sub Meta { shift }
sub Meta_BooleanKeys { @boolean_keys }
sub Meta_ScalarKeys { @scalar_keys }
@@ -176,43 +178,6 @@ sub perl_version {
$self->{values}->{perl_version} = $version;
}
-#Stolen from M::B
-my %license_urls = (
- perl => 'http://dev.perl.org/licenses/',
- apache => 'http://apache.org/licenses/LICENSE-2.0',
- artistic => 'http://opensource.org/licenses/artistic-license.php',
- artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php',
- lgpl => 'http://opensource.org/licenses/lgpl-license.php',
- lgpl2 => 'http://opensource.org/licenses/lgpl-2.1.php',
- lgpl3 => 'http://opensource.org/licenses/lgpl-3.0.html',
- bsd => 'http://opensource.org/licenses/bsd-license.php',
- gpl => 'http://opensource.org/licenses/gpl-license.php',
- gpl2 => 'http://opensource.org/licenses/gpl-2.0.php',
- gpl3 => 'http://opensource.org/licenses/gpl-3.0.html',
- mit => 'http://opensource.org/licenses/mit-license.php',
- mozilla => 'http://opensource.org/licenses/mozilla1.1.php',
- open_source => undef,
- unrestricted => undef,
- restrictive => undef,
- unknown => undef,
-);
-
-sub license {
- my $self = shift;
- return $self->{values}->{license} unless @_;
- my $license = shift or die(
- 'Did not provide a value to license()'
- );
- $self->{values}->{license} = $license;
-
- # Automatically fill in license URLs
- if ( $license_urls{$license} ) {
- $self->resources( license => $license_urls{$license} );
- }
-
- return 1;
-}
-
sub all_from {
my ( $self, $file ) = @_;
@@ -230,6 +195,8 @@ sub all_from {
die("The path '$file' does not exist, or is not a file");
}
+ $self->{values}{all_from} = $file;
+
# Some methods pull from POD instead of code.
# If there is a matching .pod, use that instead
my $pod = $file;
@@ -240,7 +207,7 @@ sub all_from {
$self->name_from($file) unless $self->name;
$self->version_from($file) unless $self->version;
$self->perl_version_from($file) unless $self->perl_version;
- $self->author_from($pod) unless $self->author;
+ $self->author_from($pod) unless @{$self->author || []};
$self->license_from($pod) unless $self->license;
$self->abstract_from($pod) unless $self->abstract;
@@ -350,6 +317,9 @@ sub version_from {
require ExtUtils::MM_Unix;
my ( $self, $file ) = @_;
$self->version( ExtUtils::MM_Unix->parse_version($file) );
+
+ # for version integrity check
+ $self->makemaker_args( VERSION_FROM => $file );
}
sub abstract_from {
@@ -360,7 +330,7 @@ sub abstract_from {
{ DISTNAME => $self->name },
'ExtUtils::MM_Unix'
)->parse_abstract($file)
- );
+ );
}
# Add both distribution and module name
@@ -385,11 +355,10 @@ sub name_from {
}
}
-sub perl_version_from {
- my $self = shift;
+sub _extract_perl_version {
if (
- Module::Install::_read($_[0]) =~ m/
- ^
+ $_[0] =~ m/
+ ^\s*
(?:use|require) \s*
v?
([\d_\.]+)
@@ -398,6 +367,16 @@ sub perl_version_from {
) {
my $perl_version = $1;
$perl_version =~ s{_}{}g;
+ return $perl_version;
+ } else {
+ return;
+ }
+}
+
+sub perl_version_from {
+ my $self = shift;
+ my $perl_version=_extract_perl_version(Module::Install::_read($_[0]));
+ if ($perl_version) {
$self->perl_version($perl_version);
} else {
warn "Cannot determine perl version info from $_[0]\n";
@@ -417,59 +396,164 @@ sub author_from {
([^\n]*)
/ixms) {
my $author = $1 || $2;
- $author =~ s{E<lt>}{<}g;
- $author =~ s{E<gt>}{>}g;
+
+ # XXX: ugly but should work anyway...
+ if (eval "require Pod::Escapes; 1") {
+ # Pod::Escapes has a mapping table.
+ # It's in core of perl >= 5.9.3, and should be installed
+ # as one of the Pod::Simple's prereqs, which is a prereq
+ # of Pod::Text 3.x (see also below).
+ $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> }
+ {
+ defined $2
+ ? chr($2)
+ : defined $Pod::Escapes::Name2character_number{$1}
+ ? chr($Pod::Escapes::Name2character_number{$1})
+ : do {
+ warn "Unknown escape: E<$1>";
+ "E<$1>";
+ };
+ }gex;
+ }
+ elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) {
+ # Pod::Text < 3.0 has yet another mapping table,
+ # though the table name of 2.x and 1.x are different.
+ # (1.x is in core of Perl < 5.6, 2.x is in core of
+ # Perl < 5.9.3)
+ my $mapping = ($Pod::Text::VERSION < 2)
+ ? \%Pod::Text::HTML_Escapes
+ : \%Pod::Text::ESCAPES;
+ $author =~ s{ E<( (\d+) | ([A-Za-z]+) )> }
+ {
+ defined $2
+ ? chr($2)
+ : defined $mapping->{$1}
+ ? $mapping->{$1}
+ : do {
+ warn "Unknown escape: E<$1>";
+ "E<$1>";
+ };
+ }gex;
+ }
+ else {
+ $author =~ s{E<lt>}{<}g;
+ $author =~ s{E<gt>}{>}g;
+ }
$self->author($author);
} else {
warn "Cannot determine author info from $_[0]\n";
}
}
-sub license_from {
+#Stolen from M::B
+my %license_urls = (
+ perl => 'http://dev.perl.org/licenses/',
+ apache => 'http://apache.org/licenses/LICENSE-2.0',
+ apache_1_1 => 'http://apache.org/licenses/LICENSE-1.1',
+ artistic => 'http://opensource.org/licenses/artistic-license.php',
+ artistic_2 => 'http://opensource.org/licenses/artistic-license-2.0.php',
+ lgpl => 'http://opensource.org/licenses/lgpl-license.php',
+ lgpl2 => 'http://opensource.org/licenses/lgpl-2.1.php',
+ lgpl3 => 'http://opensource.org/licenses/lgpl-3.0.html',
+ bsd => 'http://opensource.org/licenses/bsd-license.php',
+ gpl => 'http://opensource.org/licenses/gpl-license.php',
+ gpl2 => 'http://opensource.org/licenses/gpl-2.0.php',
+ gpl3 => 'http://opensource.org/licenses/gpl-3.0.html',
+ mit => 'http://opensource.org/licenses/mit-license.php',
+ mozilla => 'http://opensource.org/licenses/mozilla1.1.php',
+ open_source => undef,
+ unrestricted => undef,
+ restrictive => undef,
+ unknown => undef,
+);
+
+sub license {
my $self = shift;
- if (
- Module::Install::_read($_[0]) =~ m/
- (
- =head \d \s+
- (?:licen[cs]e|licensing|copyright|legal)\b
- .*?
- )
- (=head\\d.*|=cut.*|)
- \z
- /ixms ) {
- my $license_text = $1;
- my @phrases = (
- 'under the same (?:terms|license) as (?:perl|the perl programming language) itself' => 'perl', 1,
- 'GNU general public license' => 'gpl', 1,
- 'GNU public license' => 'gpl', 1,
- 'GNU lesser general public license' => 'lgpl', 1,
- 'GNU lesser public license' => 'lgpl', 1,
- 'GNU library general public license' => 'lgpl', 1,
- 'GNU library public license' => 'lgpl', 1,
- 'BSD license' => 'bsd', 1,
- 'Artistic license' => 'artistic', 1,
- 'GPL' => 'gpl', 1,
- 'LGPL' => 'lgpl', 1,
- 'BSD' => 'bsd', 1,
- 'Artistic' => 'artistic', 1,
- 'MIT' => 'mit', 1,
- 'proprietary' => 'proprietary', 0,
- );
- while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) {
- $pattern =~ s{\s+}{\\s+}g;
- if ( $license_text =~ /\b$pattern\b/i ) {
- $self->license($license);
- return 1;
- }
+ return $self->{values}->{license} unless @_;
+ my $license = shift or die(
+ 'Did not provide a value to license()'
+ );
+ $license = __extract_license($license) || lc $license;
+ $self->{values}->{license} = $license;
+
+ # Automatically fill in license URLs
+ if ( $license_urls{$license} ) {
+ $self->resources( license => $license_urls{$license} );
+ }
+
+ return 1;
+}
+
+sub _extract_license {
+ my $pod = shift;
+ my $matched;
+ return __extract_license(
+ ($matched) = $pod =~ m/
+ (=head \d \s+ L(?i:ICEN[CS]E|ICENSING)\b.*?)
+ (=head \d.*|=cut.*|)\z
+ /xms
+ ) || __extract_license(
+ ($matched) = $pod =~ m/
+ (=head \d \s+ (?:C(?i:OPYRIGHTS?)|L(?i:EGAL))\b.*?)
+ (=head \d.*|=cut.*|)\z
+ /xms
+ );
+}
+
+sub __extract_license {
+ my $license_text = shift or return;
+ my @phrases = (
+ '(?:under )?the same (?:terms|license) as (?:perl|the perl (?:\d )?programming language)' => 'perl', 1,
+ '(?:under )?the terms of (?:perl|the perl programming language) itself' => 'perl', 1,
+ 'Artistic and GPL' => 'perl', 1,
+ 'GNU general public license' => 'gpl', 1,
+ 'GNU public license' => 'gpl', 1,
+ 'GNU lesser general public license' => 'lgpl', 1,
+ 'GNU lesser public license' => 'lgpl', 1,
+ 'GNU library general public license' => 'lgpl', 1,
+ 'GNU library public license' => 'lgpl', 1,
+ 'GNU Free Documentation license' => 'unrestricted', 1,
+ 'GNU Affero General Public License' => 'open_source', 1,
+ '(?:Free)?BSD license' => 'bsd', 1,
+ 'Artistic license' => 'artistic', 1,
+ 'Apache (?:Software )?license' => 'apache', 1,
+ 'GPL' => 'gpl', 1,
+ 'LGPL' => 'lgpl', 1,
+ 'BSD' => 'bsd', 1,
+ 'Artistic' => 'artistic', 1,
+ 'MIT' => 'mit', 1,
+ 'Mozilla Public License' => 'mozilla', 1,
+ 'Q Public License' => 'open_source', 1,
+ 'OpenSSL License' => 'unrestricted', 1,
+ 'SSLeay License' => 'unrestricted', 1,
+ 'zlib License' => 'open_source', 1,
+ 'proprietary' => 'proprietary', 0,
+ );
+ while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) {
+ $pattern =~ s#\s+#\\s+#gs;
+ if ( $license_text =~ /\b$pattern\b/i ) {
+ return $license;
}
}
+ return '';
+}
- warn "Cannot determine license info from $_[0]\n";
- return 'unknown';
+sub license_from {
+ my $self = shift;
+ if (my $license=_extract_license(Module::Install::_read($_[0]))) {
+ $self->license($license);
+ } else {
+ warn "Cannot determine license info from $_[0]\n";
+ return 'unknown';
+ }
}
sub _extract_bugtracker {
- my @links = $_[0] =~ m#L<(\Qhttp://rt.cpan.org/\E[^>]+)>#g;
+ my @links = $_[0] =~ m#L<(
+ \Qhttp://rt.cpan.org/\E[^>]+|
+ \Qhttp://github.com/\E[\w_]+/[\w_]+/issues|
+ \Qhttp://code.google.com/p/\E[\w_\-]+/issues/list
+ )>#gx;
my %links;
@links{@links}=();
@links=keys %links;
@@ -485,7 +569,7 @@ sub bugtracker_from {
return 0;
}
if ( @links > 1 ) {
- warn "Found more than on rt.cpan.org link in $_[0]\n";
+ warn "Found more than one bugtracker link in $_[0]\n";
return 0;
}
@@ -532,8 +616,15 @@ sub _perl_version {
return $v;
}
-
-
+sub add_metadata {
+ my $self = shift;
+ my %hash = @_;
+ for my $key (keys %hash) {
+ warn "add_metadata: $key is not prefixed with 'x_'.\n" .
+ "Use appopriate function to add non-private metadata.\n" unless $key =~ /^x_/;
+ $self->{values}->{$key} = $hash{$key};
+ }
+}
######################################################################
@@ -6,7 +6,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.91';
+ $VERSION = '1.00';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
@@ -6,7 +6,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.91';
+ $VERSION = '1.00';
@ISA = 'Module::Install::Base';
$ISCORE = 1;
}
@@ -6,7 +6,7 @@ use Module::Install::Base ();
use vars qw{$VERSION @ISA $ISCORE};
BEGIN {
- $VERSION = '0.91';;
+ $VERSION = '1.00';
@ISA = qw{Module::Install::Base};
$ISCORE = 1;
}
@@ -26,7 +26,10 @@ sub WriteAll {
$self->check_nmake if $args{check_nmake};
unless ( $self->makemaker_args->{PL_FILES} ) {
- $self->makemaker_args( PL_FILES => {} );
+ # XXX: This still may be a bit over-defensive...
+ unless ($self->makemaker(6.25)) {
+ $self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL';
+ }
}
# Until ExtUtils::MakeMaker support MYMETA.yml, make sure
@@ -19,6 +19,9 @@ package Module::Install;
use 5.005;
use strict 'vars';
+use Cwd ();
+use File::Find ();
+use File::Path ();
use vars qw{$VERSION $MAIN};
BEGIN {
@@ -28,7 +31,7 @@ BEGIN {
# This is not enforced yet, but will be some time in the next few
# releases once we can make sure it won't clash with custom
# Module::Install extensions.
- $VERSION = '0.91';
+ $VERSION = '1.00';
# Storage for the pseudo-singleton
$MAIN = undef;
@@ -38,18 +41,25 @@ BEGIN {
}
+sub import {
+ my $class = shift;
+ my $self = $class->new(@_);
+ my $who = $self->_caller;
-
-
-
-# Whether or not inc::Module::Install is actually loaded, the
-# $INC{inc/Module/Install.pm} is what will still get set as long as
-# the caller loaded module this in the documented manner.
-# If not set, the caller may NOT have loaded the bundled version, and thus
-# they may not have a MI version that works with the Makefile.PL. This would
-# result in false errors or unexpected behaviour. And we don't want that.
-my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
-unless ( $INC{$file} ) { die <<"END_DIE" }
+ #-------------------------------------------------------------
+ # all of the following checks should be included in import(),
+ # to allow "eval 'require Module::Install; 1' to test
+ # installation of Module::Install. (RT #51267)
+ #-------------------------------------------------------------
+
+ # Whether or not inc::Module::Install is actually loaded, the
+ # $INC{inc/Module/Install.pm} is what will still get set as long as
+ # the caller loaded module this in the documented manner.
+ # If not set, the caller may NOT have loaded the bundled version, and thus
+ # they may not have a MI version that works with the Makefile.PL. This would
+ # result in false errors or unexpected behaviour. And we don't want that.
+ my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
+ unless ( $INC{$file} ) { die <<"END_DIE" }
Please invoke ${\__PACKAGE__} with:
@@ -61,26 +71,28 @@ not:
END_DIE
-
-
-
-
-# If the script that is loading Module::Install is from the future,
-# then make will detect this and cause it to re-run over and over
-# again. This is bad. Rather than taking action to touch it (which
-# is unreliable on some platforms and requires write permissions)
-# for now we should catch this and refuse to run.
-if ( -f $0 ) {
- my $s = (stat($0))[9];
-
- # If the modification time is only slightly in the future,
- # sleep briefly to remove the problem.
- my $a = $s - time;
- if ( $a > 0 and $a < 5 ) { sleep 5 }
-
- # Too far in the future, throw an error.
- my $t = time;
- if ( $s > $t ) { die <<"END_DIE" }
+ # This reportedly fixes a rare Win32 UTC file time issue, but
+ # as this is a non-cross-platform XS module not in the core,
+ # we shouldn't really depend on it. See RT #24194 for detail.
+ # (Also, this module only supports Perl 5.6 and above).
+ eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006;
+
+ # If the script that is loading Module::Install is from the future,
+ # then make will detect this and cause it to re-run over and over
+ # again. This is bad. Rather than taking action to touch it (which
+ # is unreliable on some platforms and requires write permissions)
+ # for now we should catch this and refuse to run.
+ if ( -f $0 ) {
+ my $s = (stat($0))[9];
+
+ # If the modification time is only slightly in the future,
+ # sleep briefly to remove the problem.
+ my $a = $s - time;
+ if ( $a > 0 and $a < 5 ) { sleep 5 }
+
+ # Too far in the future, throw an error.
+ my $t = time;
+ if ( $s > $t ) { die <<"END_DIE" }
Your installer $0 has a modification time in the future ($s > $t).
@@ -89,15 +101,12 @@ This is known to create infinite loops in make.
Please correct this, then run $0 again.
END_DIE
-}
-
-
-
+ }
-# Build.PL was formerly supported, but no longer is due to excessive
-# difficulty in implementing every single feature twice.
-if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" }
+ # Build.PL was formerly supported, but no longer is due to excessive
+ # difficulty in implementing every single feature twice.
+ if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" }
Module::Install no longer supports Build.PL.
@@ -107,23 +116,42 @@ Please remove all Build.PL files and only use the Makefile.PL installer.
END_DIE
+ #-------------------------------------------------------------
+ # To save some more typing in Module::Install installers, every...
+ # use inc::Module::Install
+ # ...also acts as an implicit use strict.
+ $^H |= strict::bits(qw(refs subs vars));
+ #-------------------------------------------------------------
+ unless ( -f $self->{file} ) {
+ foreach my $key (keys %INC) {
+ delete $INC{$key} if $key =~ /Module\/Install/;
+ }
-# To save some more typing in Module::Install installers, every...
-# use inc::Module::Install
-# ...also acts as an implicit use strict.
-$^H |= strict::bits(qw(refs subs vars));
-
+ local $^W;
+ require "$self->{path}/$self->{dispatch}.pm";
+ File::Path::mkpath("$self->{prefix}/$self->{author}");
+ $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
+ $self->{admin}->init;
+ @_ = ($class, _self => $self);
+ goto &{"$self->{name}::import"};
+ }
+ local $^W;
+ *{"${who}::AUTOLOAD"} = $self->autoload;
+ $self->preload;
+ # Unregister loader and worker packages so subdirs can use them again
+ delete $INC{'inc/Module/Install.pm'};
+ delete $INC{'Module/Install.pm'};
+ # Save to the singleton
+ $MAIN = $self;
-use Cwd ();
-use File::Find ();
-use File::Path ();
-use FindBin;
+ return 1;
+}
sub autoload {
my $self = shift;
@@ -136,7 +164,21 @@ sub autoload {
# Delegate back to parent dirs
goto &$code unless $cwd eq $pwd;
}
- $$sym =~ /([^:]+)$/ or die "Cannot autoload $who - $sym";
+ unless ($$sym =~ s/([^:]+)$//) {
+ # XXX: it looks like we can't retrieve the missing function
+ # via $$sym (usually $main::AUTOLOAD) in this case.
+ # I'm still wondering if we should slurp Makefile.PL to
+ # get some context or not ...
+ my ($package, $file, $line) = caller;
+ die <<"EOT";
+Unknown function is found at $file line $line.
+Execution of $file aborted due to runtime errors.
+
+If you're a contributor to a project, you may need to install
+some Module::Install extensions from CPAN (or other repository).
+If you're a user of a module, please contact the author.
+EOT
+ }
my $method = $1;
if ( uc($method) eq $method ) {
# Do nothing
@@ -152,33 +194,6 @@ sub autoload {
};
}
-sub import {
- my $class = shift;
- my $self = $class->new(@_);
- my $who = $self->_caller;
-
- unless ( -f $self->{file} ) {
- require "$self->{path}/$self->{dispatch}.pm";
- File::Path::mkpath("$self->{prefix}/$self->{author}");
- $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
- $self->{admin}->init;
- @_ = ($class, _self => $self);
- goto &{"$self->{name}::import"};
- }
-
- *{"${who}::AUTOLOAD"} = $self->autoload;
- $self->preload;
-
- # Unregister loader and worker packages so subdirs can use them again
- delete $INC{"$self->{file}"};
- delete $INC{"$self->{path}.pm"};
-
- # Save to the singleton
- $MAIN = $self;
-
- return 1;
-}
-
sub preload {
my $self = shift;
unless ( $self->{extensions} ) {
@@ -204,6 +219,7 @@ sub preload {
my $who = $self->_caller;
foreach my $name ( sort keys %seen ) {
+ local $^W;
*{"${who}::$name"} = sub {
${"${who}::AUTOLOAD"} = "${who}::$name";
goto &{"${who}::AUTOLOAD"};
@@ -214,12 +230,18 @@ sub preload {
sub new {
my ($class, %args) = @_;
+ delete $INC{'FindBin.pm'};
+ {
+ # to suppress the redefine warning
+ local $SIG{__WARN__} = sub {};
+ require FindBin;
+ }
+
# ignore the prefix on extension modules built from top level.
my $base_path = Cwd::abs_path($FindBin::Bin);
unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
delete $args{prefix};
}
-
return $args{_self} if $args{_self};
$args{dispatch} ||= 'Admin';
@@ -272,8 +294,10 @@ END_DIE
sub load_extensions {
my ($self, $path, $top) = @_;
+ my $should_reload = 0;
unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) {
unshift @INC, $self->{prefix};
+ $should_reload = 1;
}
foreach my $rv ( $self->find_extensions($path) ) {
@@ -281,12 +305,13 @@ sub load_extensions {
next if $self->{pathnames}{$pkg};
local $@;
- my $new = eval { require $file; $pkg->can('new') };
+ my $new = eval { local $^W; require $file; $pkg->can('new') };
unless ( $new ) {
warn $@ if $@;
next;
}
- $self->{pathnames}{$pkg} = delete $INC{$file};
+ $self->{pathnames}{$pkg} =
+ $should_reload ? delete $INC{$file} : $INC{$file};
push @{$self->{extensions}}, &{$new}($pkg, _top => $top );
}
@@ -348,17 +373,24 @@ sub _caller {
return $call;
}
+# Done in evals to avoid confusing Perl::MinimumVersion
+eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
sub _read {
local *FH;
- if ( $] >= 5.006 ) {
- open( FH, '<', $_[0] ) or die "open($_[0]): $!";
- } else {
- open( FH, "< $_[0]" ) or die "open($_[0]): $!";
- }
+ open( FH, '<', $_[0] ) or die "open($_[0]): $!";
+ my $string = do { local $/; <FH> };
+ close FH or die "close($_[0]): $!";
+ return $string;
+}
+END_NEW
+sub _read {
+ local *FH;
+ open( FH, "< $_[0]" ) or die "open($_[0]): $!";
my $string = do { local $/; <FH> };
close FH or die "close($_[0]): $!";
return $string;
}
+END_OLD
sub _readperl {
my $string = Module::Install::_read($_[0]);
@@ -379,18 +411,26 @@ sub _readpod {
return $string;
}
+# Done in evals to avoid confusing Perl::MinimumVersion
+eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
sub _write {
local *FH;
- if ( $] >= 5.006 ) {
- open( FH, '>', $_[0] ) or die "open($_[0]): $!";
- } else {
- open( FH, "> $_[0]" ) or die "open($_[0]): $!";
+ open( FH, '>', $_[0] ) or die "open($_[0]): $!";
+ foreach ( 1 .. $#_ ) {
+ print FH $_[$_] or die "print($_[0]): $!";
}
+ close FH or die "close($_[0]): $!";
+}
+END_NEW
+sub _write {
+ local *FH;
+ open( FH, "> $_[0]" ) or die "open($_[0]): $!";
foreach ( 1 .. $#_ ) {
print FH $_[$_] or die "print($_[0]): $!";
}
close FH or die "close($_[0]): $!";
}
+END_OLD
# _version is for processing module versions (eg, 1.03_05) not
# Perl versions (eg, 5.8.1).
@@ -427,4 +467,4 @@ sub _CLASS ($) {
1;
-# Copyright 2008 - 2009 Adam Kennedy.
+# Copyright 2008 - 2010 Adam Kennedy.
@@ -48,13 +48,13 @@ after tree => sub {
my ( $self, $c ) = @_;
my $repository = $c->stash->{Repository};
my $commit = $c->stash->{Commit};
- my $tree = $c->stash->{filename}
- ? $repository->get_object($repository->hash_by_path($commit->sha1, $c->stash->{filename}))
- : $repository->get_object($commit->tree_sha1)
+ my $tree_obj = $c->stash->{filename}
+ ? $commit->sha_by_path($c->stash->{filename})
+ : $commit->tree->[0]
;
$c->stash(
- tree => $tree,
- tree_list => [$repository->list_tree($tree->sha1)],
+ tree => $tree_obj,
+ tree_list => $tree_obj->tree,
);
};
@@ -98,12 +98,8 @@ after history => sub {
($filename ? (file => $filename) : ())
);
- my $file = $repository->get_object(
- $repository->hash_by_path(
- $repository->head_hash,
- $filename
- )
- );
+ my $commit = $repository->get_object('HEAD');
+ my $file = $commit->sha_by_path($filename);
my $page = $c->req->param('pg') || 0;
$logargs{skip} = $c->req->param('pg') * $logargs{count}
@@ -0,0 +1,79 @@
+use MooseX::Declare;
+
+class Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive
+ with Gitalist::Git::CollectionOfRepositories {
+
+ use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
+ use MooseX::Types::Path::Class qw/Dir/;
+
+ use Moose::Autobox;
+ use List::Util 'first';
+
+ has repo_dir => (
+ isa => Dir,
+ is => 'ro',
+ required => 1,
+ coerce => 1,
+ );
+
+ method BUILD {
+ # Make sure repo_dir is an absolute path so that ->contains() works correctly.
+ $self->repo_dir->resolve;
+ }
+
+ method _find_repos(Dir $dir) {
+ return map {
+ $self->_is_git_repo($_) ? $_ : $self->_find_repos($_)
+ } grep $_->is_dir, $dir->children;
+ }
+
+ method _get_path_for_repository_name (NonEmptySimpleStr $name) {
+ my $repo = first { $_->name eq $name } $self->repositories->flatten
+ or return;
+ return $repo->path;
+ }
+
+ ## Builders
+ method _build_repositories {
+ return [
+ map Gitalist::Git::Repository->new($_), $self->_find_repos( $self->repo_dir )
+ ];
+ }
+} # end class
+
+__END__
+
+=head1 NAME
+
+Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive - Model of recursive directories containing git repositories
+
+=head1 SYNOPSIS
+
+ my $repo = Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive->new( repo_dir => $Dir );
+ my $repository_list = $repo->repositories;
+ my $first_repository = $repository_list->[0];
+ my $named_repository = $repo->get_repository('Gitalist');
+
+=head1 DESCRIPTION
+
+This class provides a list of Repositories recursively found in the given directory.
+
+=head1 ATTRIBUTES
+
+=head2 repo_dir (C<Path::Class::Dir>)
+
+The filesystem root of the C<Repo>.
+
+=head1 SEE ALSO
+
+L<Gitalist::Git::CollectionOfRepositories>, L<Gitalist::Git::Repository>
+
+=head1 AUTHORS
+
+See L<Gitalist> for authors.
+
+=head1 LICENSE
+
+See L<Gitalist> for the license.
+
+=cut
@@ -14,11 +14,12 @@ role Gitalist::Git::CollectionOfRepositories {
);
method get_repository (NonEmptySimpleStr $name) {
my $path = $self->_get_path_for_repository_name($name);
- die "Not a valid git repository."
+ die "Couldn't get_repository '$name' - not a valid git repository."
unless $self->_is_git_repo($path);
return Repository->new( $path );
}
# Determine whether a given directory is a git repo.
+ # http://www.kernel.org/pub/software/scm/git/docs/gitrepository-layout.html
method _is_git_repo ($dir) {
return -f $dir->file('HEAD') || -f $dir->file('.git', 'HEAD');
}
@@ -0,0 +1,57 @@
+package Gitalist::Git::Head;
+use Moose;
+use namespace::autoclean;
+
+use Gitalist::Git::Types qw/SHA1/;
+use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
+use MooseX::Types::DateTime;
+use DateTime;
+
+has sha1 => ( isa => SHA1,
+ is => 'ro',
+ required => 1,
+ );
+has name => ( isa => NonEmptySimpleStr,
+ is => 'ro',
+ required => 1,
+ );
+has committer => ( isa => NonEmptySimpleStr,
+ is => 'ro',
+ required => 1,
+ );
+has last_change => ( isa => 'DateTime',
+ is => 'ro',
+ required => 1,
+ coerce => 1,
+);
+
+around BUILDARGS => sub {
+ my $orig = shift;
+ my $class = shift;
+
+ if ( @_ == 1 && ! ref $_[0] ) {
+ my $line = $_[0];
+ # expects $line to match the output from
+ # for-each-ref --format=%(objectname)%00%(refname)%00%(committer)
+ my ($sha1, $name, $commitinfo) = split /\0/, $line, 3;
+ $name =~ s!^refs/heads/!!;
+
+ my ($committer, $epoch, $tz) =
+ $commitinfo =~ /(.*)\s(\d+)\s+([+-]\d+)$/;
+ my $dt = DateTime->from_epoch(
+ epoch => $epoch,
+ time_zone => $tz,
+ );
+
+ return $class->$orig(
+ sha1 => $sha1,
+ name => $name,
+ committer => $committer,
+ last_change => $dt,
+ );
+ } else {
+ return $class->$orig(@_);
+ }
+};
+
+1;
@@ -23,6 +23,23 @@ class Gitalist::Git::Object::Commit
],
);
+ method _build_tree {
+ return [$self->repository->get_object($self->tree_sha1)];
+ }
+
+ method sha_by_path ($path) {
+ $path =~ s{/+$}();
+ # FIXME should this really just take the first result?
+ my @paths = $self->repository->run_cmd('ls-tree', $self->sha1, '--', $path)
+ or return;
+ my $line = $paths[0];
+
+ #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c'
+ $line =~ m/^([0-9]+) (.+) ($SHA1RE)\t/;
+ my $sha1 = $3;
+ return $self->repository->get_object($sha1);
+ }
+
method get_patch ( Maybe[NonEmptySimpleStr] $parent_hash?,
Int $patch_count?) {
# assembling the git command to execute...
@@ -233,6 +250,10 @@ Subclass of C<Gitalist::Git::Object>.
=head1 METHODS
+=head2 sha_by_path ($path)
+
+Returns the tree/file sha1 for a given path in a commit.
+
=head2 get_patch
=head2 diff
@@ -1,9 +1,10 @@
use MooseX::Declare;
use Moose::Autobox;
-class Gitalist::Git::Object {
+class Gitalist::Git::Object is dirty {
use MooseX::Types::Moose qw/Str Int Bool Maybe ArrayRef/;
use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
+ use overload '""' => '_to_string', fallback => 1;
# repository and sha1 are required initargs
has repository => ( isa => 'Gitalist::Git::Repository',
@@ -50,6 +51,9 @@ class Gitalist::Git::Object {
method BUILD { $self->$_() for qw/_gpp_obj size modestr/ }
## Private methods
+ method _to_string {
+ return $self->sha1;
+ };
## Builders
method _build__gpp_obj {
@@ -15,6 +15,8 @@ class Gitalist::Git::Repository with Gitalist::Git::HasUtils {
use Gitalist::Git::Object::Tree;
use Gitalist::Git::Object::Commit;
use Gitalist::Git::Object::Tag;
+ use Gitalist::Git::Head;
+ use Gitalist::Git::Tag;
our $SHA1RE = qr/[0-9a-fA-F]{40}/;
@@ -23,7 +25,12 @@ class Gitalist::Git::Repository with Gitalist::Git::HasUtils {
# Last path component becomes $self->name
# Full path to git objects becomes $self->path
my $name = $dir->dir_list(-1);
- $dir = $dir->subdir('.git') if (-f $dir->file('.git', 'HEAD'));
+ if(-f $dir->file('.git', 'HEAD')) { # Non-bare repo above .git
+ $dir = $dir->subdir('.git');
+ $name = $dir->dir_list(-2, 1); # .../name/.git
+ } elsif('.git' eq $dir->dir_list(-1)) { # Non-bare repo in .git
+ $name = $dir->dir_list(-2);
+ }
confess("Can't find a git repository at " . $dir)
unless ( -f $dir->file('HEAD') );
return $class->$orig(name => $name,
@@ -59,10 +66,10 @@ class Gitalist::Git::Repository with Gitalist::Git::HasUtils {
? 1 : 0
},
);
- has heads => ( isa => ArrayRef[HashRef],
+ has heads => ( isa => ArrayRef['Gitalist::Git::Head'],
is => 'ro',
lazy_build => 1);
- has tags => ( isa => ArrayRef[HashRef],
+ has tags => ( isa => ArrayRef['Gitalist::Git::Tag'],
is => 'ro',
lazy_build => 1);
has references => ( isa => HashRef[ArrayRef[Str]],
@@ -75,11 +82,6 @@ class Gitalist::Git::Repository with Gitalist::Git::HasUtils {
## Public methods
- method get_object_or_head (NonEmptySimpleStr $ref) {
- my $sha1 = is_SHA1($ref) ? $ref : $self->head_hash($ref);
- $self->get_object($sha1);
- }
-
method head_hash (Str $head?) {
my $output = $self->run_cmd(qw/rev-parse --verify/, $head || 'HEAD' );
confess("No such head: " . $head) unless defined $output;
@@ -88,12 +90,6 @@ class Gitalist::Git::Repository with Gitalist::Git::HasUtils {
return $sha1;
}
- method list_tree (SHA1 $sha1?) {
- $sha1 ||= $self->head_hash;
- my $object = $self->get_object($sha1);
- return @{$object->tree};
- }
-
method get_object (NonEmptySimpleStr $sha1) {
unless (is_SHA1($sha1)) {
$sha1 = $self->head_hash($sha1);
@@ -108,20 +104,6 @@ class Gitalist::Git::Repository with Gitalist::Git::HasUtils {
);
}
- method hash_by_path ($base, $path = '', $type?) {
- $path =~ s{/+$}();
- # FIXME should this really just take the first result?
- my @paths = $self->run_cmd('ls-tree', $base, '--', $path)
- or return;
- my $line = $paths[0];
-
- #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c'
- $line =~ m/^([0-9]+) (.+) ($SHA1RE)\t/;
- return defined $type && $type ne $2
- ? ()
- : $3;
- }
-
method list_revs ( NonEmptySimpleStr :$sha1!,
Int :$count?,
Int :$skip?,
@@ -262,19 +244,8 @@ class Gitalist::Git::Repository with Gitalist::Git::HasUtils {
my @revlines = $self->run_cmd_list(qw/for-each-ref --sort=-committerdate /, '--format=%(objectname)%00%(refname)%00%(committer)', 'refs/heads');
my @ret;
for my $line (@revlines) {
- my ($rev, $head, $commiter) = split /\0/, $line, 3;
- $head =~ s!^refs/heads/!!;
-
- push @ret, { sha1 => $rev, name => $head };
-
- #FIXME: That isn't the time I'm looking for..
- if (my ($epoch, $tz) = $line =~ /\s(\d+)\s+([+-]\d+)$/) {
- my $dt = DateTime->from_epoch(epoch => $epoch);
- $dt->set_time_zone($tz);
- $ret[-1]->{last_change} = $dt;
- }
+ push @ret, Gitalist::Git::Head->new($line);
}
-
return \@ret;
}
@@ -286,21 +257,8 @@ class Gitalist::Git::Repository with Gitalist::Git::HasUtils {
);
my @ret;
for my $line (@revlines) {
- my($refinfo, $creatorinfo) = split /\0/, $line;
- my($rev, $type, $name, $refid, $reftype, $title) = split(' ', $refinfo, 6);
- my($creator, $epoch, $tz) = ($creatorinfo =~ /^(.*) ([0-9]+) (.*)$/);
- $name =~ s!^refs/tags/!!;
-
- push @ret, { sha1 => $rev, name => $name };
-
- #FIXME: That isn't the time I'm looking for..
- if($epoch and $tz) {
- my $dt = DateTime->from_epoch(epoch => $epoch);
- $dt->set_time_zone($tz);
- $ret[-1]->{last_change} = $dt;
- }
+ push @ret, Gitalist::Git::Tag->new($line);
}
-
return \@ret;
}
@@ -391,20 +349,10 @@ Hashref of ArrayRefs for each reference.
Return the sha1 for HEAD, or any specified head.
-=head2 list_tree ($sha1?)
-
-Return an array of contents for a given tree.
-The tree is specified by sha1, and defaults to HEAD.
-Each item is a L<Gitalist::Git::Object>.
-
=head2 get_object ($sha1)
Return an appropriate subclass of L<Gitalist::Git::Object> for the given sha1.
-=head2 hash_by_path ($sha1, $path, $type?)
-
-Returns the sha1 for a given path, optionally limited by type.
-
=head2 list_revs ($sha1, $count?, $skip?, \%search?, $file?)
Returns a list of revs for the given head ($sha1).
@@ -0,0 +1,79 @@
+package Gitalist::Git::Tag;
+use Moose;
+use namespace::autoclean;
+
+use Gitalist::Git::Types qw/SHA1/;
+use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
+use MooseX::Types::Moose qw/Maybe Str/;
+use MooseX::Types::DateTime;
+use DateTime;
+
+has sha1 => ( isa => SHA1,
+ is => 'ro',
+ required => 1,
+ );
+has name => ( isa => NonEmptySimpleStr,
+ is => 'ro',
+ required => 1,
+ );
+
+has type => ( isa => NonEmptySimpleStr,
+ is => 'ro',
+ required => 1,
+ );
+
+has ref_sha1 => ( isa => Maybe[SHA1],
+ is => 'ro',
+ required => 0,
+ );
+has ref_type => ( isa => Maybe[NonEmptySimpleStr],
+ is => 'ro',
+ required => 0,
+ );
+has committer => ( isa => NonEmptySimpleStr,
+ is => 'ro',
+ required => 1,
+ );
+has last_change => ( isa => 'DateTime',
+ is => 'ro',
+ required => 1,
+ coerce => 1,
+);
+
+around BUILDARGS => sub {
+ my $orig = shift;
+ my $class = shift;
+
+ if ( @_ == 1 && ! ref $_[0] ) {
+ my $line = $_[0];
+ # expects $line to match the output from
+ # --format=%(objectname) %(objecttype) %(refname) %(*objectname) %(*objecttype) %(subject)%00%(creator)
+ my ($sha1, $type, $name, $ref_sha1, $ref_type, $rest) = split / /, $line, 6;
+ $name =~ s!^refs/tags/!!;
+
+ unless ($ref_sha1) {
+ ($ref_sha1, $ref_type) = (undef, undef);
+ }
+ my ($subject, $commitinfo) = split /\0/, $rest, 2;
+ my ($committer, $epoch, $tz) =
+ $commitinfo =~ /(.*)\s(\d+)\s+([+-]\d+)$/;
+ my $dt = DateTime->from_epoch(
+ epoch => $epoch,
+ time_zone => $tz,
+ );
+
+ return $class->$orig(
+ sha1 => $sha1,
+ name => $name,
+ type => $type,
+ committer => $committer,
+ last_change => $dt,
+ ref_sha1 => $ref_sha1,
+ ref_type => $ref_type,
+ );
+ } else {
+ return $class->$orig(@_);
+ }
+};
+
+1;
@@ -1,7 +1,7 @@
package Gitalist::Model::CollectionOfRepos;
use Moose;
-use Gitalist::Git::CollectionOfRepositories::FromDirectory;
+use Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive;
use Gitalist::Git::CollectionOfRepositories::FromListOfDirectories;
use MooseX::Types::Moose qw/Maybe ArrayRef/;
use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
@@ -71,7 +71,7 @@ sub build_per_context_instance {
Gitalist::Git::CollectionOfRepositories::FromListOfDirectories->new(repos => $self->repos);
}
else {
- Gitalist::Git::CollectionOfRepositories::FromDirectory->new(repo_dir => $self->repo_dir);
+ Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive->new(repo_dir => $self->repo_dir);
}
}
@@ -20,7 +20,7 @@ after 'base' => sub {
sub find : Chained('base') PathPart('') CaptureArgs(1) {
my ($self, $c, $sha1part) = @_;
# FIXME - Should not be here!
- $c->stash->{Commit} = $c->stash->{Repository}->get_object_or_head($sha1part)
+ $c->stash->{Commit} = $c->stash->{Repository}->get_object($sha1part)
or $c->detach('/error404', "Couldn't find a object for '$sha1part' in XXXX!");
$c->stash->{data} = $c->stash->{Commit};
}
@@ -34,7 +34,7 @@ sub _set_diff_args {
$c->stash(parent => shift @rest)
if @rest == 2
# Check that the single arg is unlikely to be a path.
- or @rest && to_SHA1($rest[0]) && $c->stash->{Repository}->get_object_or_head($rest[0]);
+ or @rest && to_SHA1($rest[0]) && $c->stash->{Repository}->get_object($rest[0]);
$c->stash(filename => $rest[-1])
if @rest;
}
@@ -63,15 +63,20 @@ sub tree : Chained('find') Does('FilenameArgs') Args() {}
sub find_blob : Action {
my ($self, $c) = @_;
my($repo, $object) = @{$c->{stash}}{qw(Repository Commit)};
+
# FIXME - Eugh!
- my $h = $object->isa('Gitalist::Git::Object::Commit')
- ? $repo->hash_by_path($object->sha1, $c->stash->{filename})
- : $object->isa('Gitalist::Git::Object::Blob')
- ? $object->sha1
- : die "Unknown object type for '${\$object->sha1}'";
+ my $blob;
+ if ($object->isa('Gitalist::Git::Object::Commit')) {
+ $blob = $object->sha_by_path($c->stash->{filename});
+ } elsif ($object->isa('Gitalist::Git::Object::Blob')) {
+ $blob = $object;
+ } else {
+ die "Unknown object type for '${\$object->sha1}'";
+ }
die "No file or sha1 provided."
- unless $h;
- $c->stash(blob => $repo->get_object($h)->content);
+ unless $blob;
+
+ $c->stash(blob => $blob->content);
}
sub blob : Chained('find') Does('FilenameArgs') Args() {
@@ -14,7 +14,7 @@ use Catalyst qw/
SubRequest
/;
-our $VERSION = '0.002006';
+our $VERSION = '0.002007';
$VERSION = eval $VERSION;
__PACKAGE__->config(
@@ -60,6 +60,8 @@ sub uri_with {
__END__
+=encoding UTF-8
+
=head1 NAME
Gitalist - A modern git web viewer
@@ -71,7 +73,7 @@ Gitalist - A modern git web viewer
=head1 INSTALL
As Gitalist follows the usual Perl module format the usual approach
-for installation should work e.g.
+for installation should work, e.g.:
perl Makefile.PL
make
@@ -82,20 +84,22 @@ or
cpan -i Gitalist
-You can also check gitalist out from git and run it, in this case you'll additionally
-need the author modules, but no configuration will be needed as it will default to looking
+You can also L<check Gitalist out from its git repository|/"GETTING GITALIST">
+and run it, in this case you'll additionally need the author modules,
+but no configuration will be needed as it will default to looking
for repositories the directory above the checkout.
=head1 DESCRIPTION
-Gitalist is a web frontend for git repositories based on gitweb.cgi
-and backed by Catalyst.
+Gitalist is a web frontend for git repositories based on
+L<gitweb.cgi|https://git.wiki.kernel.org/index.php/Gitweb> and backed by
+L<Catalyst>.
=head2 History
-This project started off as an attempt to port gitweb.cgi to a
+This project started off as an attempt to port I<gitweb.cgi> to a
Catalyst app in a piecemeal fashion. As it turns out, thanks largely
-to Florian Ragwitz's earlier effort, it was easier to use gitweb.cgi
+to Florian Ragwitz's earlier effort, it was easier to use I<gitweb.cgi>
as a template for building a new Catalyst application.
=head1 GETTING GITALIST
@@ -110,7 +114,8 @@ The canonical repository for the master branch is:
git://git.shadowcat.co.uk/catagits/Gitalist.git
-Gitalist is also mirrored to github, and a number of people have active forks
+Gitalist is also mirrored to GitHub at L<https://github.com/broquaint/Gitalist>,
+and a number of people have active forks
with branches and/or new features in the master branch.
=head1 BOOTSTRAPPING
@@ -120,10 +125,10 @@ own directory by installing its prerequisites locally with the help of
L<local::lib>. So instead of installing the prerequisites to the
system path with CPAN they are installed under the Gitalist directory.
-To do this clone Gitalist from the Shadowcat repository mentioned
-above or grab a snapshot from broquaint's github repository:
+To do this clone Gitalist from the L<Shadowcat repository mentioned
+above|/"GETTING GITALIST"> or grab a snapshot from broquaint's GitHub repository:
- http://github.com/broquaint/Gitalist/downloads
+ https://github.com/broquaint/Gitalist/downloads
With the source acquired and unpacked run the following from within the
Gitalist directory:
@@ -133,7 +138,7 @@ Gitalist directory:
This will install the necessary modules for the build process which in
turn installs the prerequisites locally.
-I<NB> The relevant bootstrap scripts aren't available in the CPAN dist
+B<NB:> The relevant bootstrap scripts aren't available in the CPAN dist
as the bootstrap scripts should not be installed.
=head1 INITIAL CONFIGURATION
@@ -164,7 +169,8 @@ by running:
cp `perl -Ilib -MGitalist -e'print Gitalist->path_to("gitalist.conf")'` gitalist.conf
-You can then edit this confg, adding a repo_dir path and customising other settings as desired.
+You can then edit this configuration, adding a C<repo_dir> path and customising
+other settings as desired.
You can then start the Gitalist demo server by setting C<< GITALIST_CONFIG >>. For example:
@@ -187,7 +193,7 @@ to run it in a more production facing environment than using the single threaded
server.
The recommended deployment method for Gitalist is FastCGI, although Gitalist can also be run
-under mod_perl or as pure perl with L<Catalyst::Engine::PreFork>.
+under L<mod_perl|https://perl.apache.org/> or as pure Perl with L<Catalyst::Engine::PreFork>.
Assuming that you have installed Gitalist's dependencies into a L<local::lib>, and you
are running from a git checkout, adding a trivial FCGI script as C<script/gitalist.fcgi>
@@ -199,45 +205,50 @@ are running from a git checkout, adding a trivial FCGI script as C<script/gitali
This example can be seen live here:
http://example.gitalist.com
-
+
=head2 FASTCGI
- Running Gitalist in FastCGI mode requires a webserver with FastCGI
- support (such as apache with mod_fcgi or fcgid). Below is a sample
- configuration using Apache2 with fcgid in a dynamic configuration
- (as opposed to static or standalone mode). More information on these modes and
- their configuration can be found at
- http://search.cpan.org/~bobtfish/Catalyst-Runtime-5.80025/lib/Catalyst/Engine/FastCGI.pm#Standalone_server_mode
-
- In Apache's mime.conf, add AddHandler fcgid-script .fcgi (or AddHandler fastcgi-script .fcgi for mod_fcgi)
-
- And a quick VirtualHost configuration:
-
- <VirtualHost *:80>
- ServerName gitalist.yourdomain.com
- DocumentRoot /path/to/gitalist.fcgi
- <Directory "/path/to/gitalist.fcgi">
+
+Running Gitalist in FastCGI mode requires a webserver with FastCGI
+support (such as apache with L<mod_fcgi|http://www.fastcgi.com/drupal/node/3>
+or L<mod_fcgid|https://httpd.apache.org/mod_fcgid/>). Below is a sample
+configuration using Apache2 with mod_fcgid in a dynamic configuration
+(as opposed to static or standalone mode). More information on these modes and
+their configuration can be found at L<Catalyst::Engine::FastCGI/"Standalone server mode">.
+
+In Apache's F<mime.conf>, add C<AddHandler fcgid-script .fcgi>
+(or C<AddHandler fastcgi-script .fcgi> for mod_fcgi).
+
+And a quick VirtualHost configuration:
+
+ <VirtualHost *:80>
+ ServerName gitalist.yourdomain.com
+ DocumentRoot /path/to/gitalist.fcgi
+ <Directory "/path/to/gitalist.fcgi">
AllowOverride all
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
- </Directory>
+ </Directory>
# Tell Apache this is a FastCGI application
<Files gitalist.fcgi>
#change the below to fastcgi-script if using mod_fcgi
SetHandler fcgid-script
</Files>
- </VirtualHost>
-
- Now to access your gitalist instance, you'll go to gitalist.yourdomain.com/gitalist.fcgi/
- (DO NOT FORGET THAT TRAILING /). If you'd like a different URL, of course, you'll likely want to use
- mod_rewrite or equivalent
-
- If you find the need to do some troubleshooting, you can call http://url_to_gitalist.fcgi?dump_info=1
- and/or add export GITALIST_DEBUG=1 to the top of you gitalist.fcgi file (just below the shebang line).
-
- Also, note that Apache will refuse %2F in Gitalist URL's unless configured otherwise. Make sure
- "AllowEncodedSlashes On" is in your httpd.conf file in order for this to run smoothly.
+ </VirtualHost>
+
+Now to access your Gitalist instance, you'll go to
+C<gitalist.yourdomain.com/gitalist.fcgi/> (B<do not forget that trailing> C</>).
+If you'd like a different URL, of course, you'll likely want to use
+L<mod_rewrite|https://httpd.apache.org/docs/mod/mod_rewrite.html> or equivalent.
+
+If you find the need to do some troubleshooting, you can call
+C<http://url_to_gitalist.fcgi?dump_info=1> and/or add export C<GITALIST_DEBUG=1>
+to the top of your F<gitalist.fcgi> file (just below the shebang line).
+
+Also, note that Apache will refuse C<%2F> in Gitalist URLs
+unless configured otherwise. Make sure C<AllowEncodedSlashes On>
+is in your F<httpd.conf> file in order for this to run smoothly.
=head1 CONTRIBUTING
@@ -263,19 +274,17 @@ L<Catalyst>
=head1 AUTHORS AND COPYRIGHT
Catalyst application:
- (C) 2009 Venda Ltd and Dan Brook <broq@cpan.org>
- (C) 2009, Tom Doran <bobtfish@bobtfish.net>
- (C) 2009, Zac Stevens <zts@cryptocracy.com>
+ © 2009 Venda Ltd and Dan Brook <broq@cpan.org>
+ © 2009, Tom Doran <bobtfish@bobtfish.net>
+ © 2009, Zac Stevens <zts@cryptocracy.com>
Original gitweb.cgi from which this was derived:
- (C) 2005-2006, Kay Sievers <kay.sievers@vrfy.org>
- (C) 2005, Christian Gierke
+ © 2005-2006, Kay Sievers <kay.sievers@vrfy.org>
+ © 2005, Christian Gierke
Model based on http://github.com/rafl/gitweb
- (C) 2008, Florian Ragwitz
+ © 2008, Florian Ragwitz
=head1 LICENSE
Licensed under GNU GPL v2
-
-=cut
diff --git a/var/tmp/source/BROQ/Gitalist-0.002007/Gitalist-0.002007/root/favicon_gif.ico b/var/tmp/source/BROQ/Gitalist-0.002007/Gitalist-0.002007/root/favicon_gif.ico
new file mode 100755
index 00000000..fea2fec4
Binary files /dev/null and b/var/tmp/source/BROQ/Gitalist-0.002007/Gitalist-0.002007/root/favicon_gif.ico differ
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -1,6 +1,6 @@
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -0,0 +1,55 @@
+use FindBin qw/$Bin/;
+BEGIN {
+ my $env = "$FindBin::Bin/../script/env";
+ if (-r $env) {
+ do $env or die $@;
+ }
+}
+
+use strict;
+use warnings;
+use Test::More qw/no_plan/;
+use Test::Exception;
+use Path::Class::Dir;
+
+BEGIN { use_ok 'Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive' }
+
+my $repo_dir = "$Bin/lib/repositories";
+my $repo = Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive->new( repo_dir => $repo_dir );
+isa_ok($repo, 'Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive');
+
+is($repo->repo_dir, $repo_dir, "repo->repo_dir is correct" );
+
+# 'bare.git' is a bare git repository in the repository dir
+
+my $repository_list = $repo->repositories;
+is( scalar @{$repository_list}, 5, '->repositories is an array with the correct number of members' );
+isa_ok($repository_list->[0], 'Gitalist::Git::Repository');
+my @sorted_names = sort map { $_->{name} } @{$repository_list};
+is_deeply( \@sorted_names, [ qw( bare.git barerecursive.git nodescription repo1 scratch.git) ], 'Repositories are correctly loaded' );
+
+dies_ok {
+ my $repository = $repo->get_repository("NoSuchRepository");
+} 'throws exception for invalid repository';
+
+dies_ok {
+ my $repository = $repo->get_repository();
+} 'throws exception for no repository';
+
+dies_ok {
+ my $repository = $repo->get_repository('../../../');
+} 'Relative directory not contained within repo_dir';
+
+my $repository = $repo->get_repository( "repo1" );
+isa_ok($repository, 'Gitalist::Git::Repository');
+
+$repository = $repo->get_repository( "scratch.git" );
+isa_ok($repository, 'Gitalist::Git::Repository');
+
+# check for bug where get_repository blew up if repo_dir
+# was a relative path
+lives_ok {
+ my $repo2_dir = "$Bin/lib/../lib/repositories";
+ my $repo2 = Gitalist::Git::CollectionOfRepositories::FromDirectoryRecursive->new( repo_dir => $repo2_dir );
+ my $repo2_proj = $repo2->get_repository("repo1");
+} 'relative repo_dir properly handled';
@@ -1,6 +1,6 @@
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -50,34 +50,31 @@ ok(keys %references >= 2, '->references hash has elements');
is($references{'36c6c6708b8360d7023e8a1649c45bcf9b3bd818'}->[0], 'heads/master', 'reference looks ok');
my @heads = @{$proj->heads};
ok(scalar @heads > 1, '->heads list has more than one element');
-my %head = %{$heads[1]};
-ok(keys %head == 3, '->heads[1] has the right number of keys');
-ok(defined $head{sha1}, '->heads[1]-sha1 is defined');
-ok(defined $head{name}, '->heads[1]-name is defined');
+my $head = $heads[1];
+isa_ok($head, 'Gitalist::Git::Head');
is($proj->head_hash, '36c6c6708b8360d7023e8a1649c45bcf9b3bd818', 'head_hash for HEAD is correct');
is($proj->head_hash('refs/heads/master'), '36c6c6708b8360d7023e8a1649c45bcf9b3bd818', 'head_hash for refs/heads/master is correct');
is($proj->head_hash('rafs/head/mister'), undef, 'head_hash for rafs/head/mister is undef');
-is(scalar $proj->list_tree, 2, 'expected number of entries in tree');
-isa_ok(($proj->list_tree)[1], 'Gitalist::Git::Object');
+ok(scalar @{$proj->tags} == 1, '->tags list has one element');
# Return an ::Object from a sha1
my $obj1 = $proj->get_object('729a7c3f6ba5453b42d16a43692205f67fb23bc1');
isa_ok($obj1, 'Gitalist::Git::Object::Tree');
-my $hbp_sha1 = $proj->hash_by_path('36c6c6708b8360d7023e8a1649c45bcf9b3bd818', 'dir1/file2');
-my $obj2 = $proj->get_object($hbp_sha1);
-isa_ok($obj2, 'Gitalist::Git::Object::Blob');
-is($obj2->type, 'blob', 'hash_by_path obj is a file');
-is($obj2->content, "foo\n", 'hash_by_path obj is a file');
-
my $obj3 = $proj->get_object($proj->head_hash);
isa_ok($obj3, 'Gitalist::Git::Object::Commit');
+my $obj2 = $obj3->sha_by_path('dir1/file2');
+isa_ok($obj2, 'Gitalist::Git::Object::Blob');
+is($obj2->type, 'blob', 'sha_by_path obj is a blob');
+is($obj2->content, "foo\n", 'sha_by_path obj content is correct');
+
+
like($proj->head_hash('HEAD'), qr/^([0-9a-fA-F]{40})$/, 'head_hash');
{
- my @tree = $proj->list_tree('3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
+ my @tree = @{$obj3->tree};
is(scalar @tree, 1, "tree array contains one entry.");
isa_ok($tree[0], 'Gitalist::Git::Object', 'tree element 0');
}
@@ -0,0 +1,35 @@
+use FindBin qw/$Bin/;
+BEGIN {
+ my $env = "$FindBin::Bin/../script/env";
+ if (-r $env) {
+ do $env or die $@;
+ }
+}
+
+use strict;
+use warnings;
+use Test::More qw/no_plan/;
+use Test::Exception;
+use Data::Dumper;
+
+BEGIN { use_ok 'Gitalist::Git::Head' }
+
+
+my $revline="a92fb1c9282f7319099ce7f783c8be7d5360f6e3\0refs/heads/model-cleanup\0Zachary Stevens <zts\@cryptocracy.com> 1277601094 +0100";
+my $instance = Gitalist::Git::Head->new($revline);
+isa_ok($instance, 'Gitalist::Git::Head');
+
+# Create an instance, passing last_change as a DateTime
+use DateTime;
+my $timespec = [1277578462, '+0100'];
+my $dt = DateTime->from_epoch(
+ epoch => @$timespec[0],
+ time_zone => @$timespec[1],
+);
+my $head = Gitalist::Git::Head->new(
+ sha1 => 'bca1153c22e393a952b6715bf2212901e4e77215',
+ name => 'master',
+ committer => 'Zachary Stevens <zts@cryptocracy.com>',
+ last_change => $dt,
+);
+isa_ok($head, 'Gitalist::Git::Head');
@@ -1,6 +1,6 @@
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -39,6 +39,7 @@ is($object->file, 'dir1', 'file is correct');
is($object->mode, 16384, 'mode is correct');
is($object->modestr, 'drwxr-xr-x', "modestr is correct" );
is($object->size, 33, "size is correct");
+is($object,'729a7c3f6ba5453b42d16a43692205f67fb23bc1', 'stringifies correctly');
# Create object from sha1.
my $obj2 = Gitalist::Git::Object::Blob->new(
@@ -64,6 +65,7 @@ my $commit_obj = Gitalist::Git::Object::Commit->new(
sha1 => '3f7567c7bdf7e7ebf410926493b92d398333116e',
);
isa_ok($commit_obj, 'Gitalist::Git::Object::Commit', "commit object");
+isa_ok($commit_obj->tree->[0], 'Gitalist::Git::Object::Tree');
my ($tree, $patch) = $commit_obj->diff(
patch => 1,
);
@@ -0,0 +1,36 @@
+use FindBin qw/$Bin/;
+BEGIN {
+ my $env = "$FindBin::Bin/../script/env";
+ if (-r $env) {
+ do $env or die $@;
+ }
+}
+use strict;
+use warnings;
+use Test::More qw/no_plan/;
+use Test::Exception;
+use Data::Dumper;
+
+BEGIN { use_ok 'Gitalist::Git::Tag' }
+
+# Create an instance from for-each-ref output
+my $revline="36c6c6708b8360d7023e8a1649c45bcf9b3bd818 commit refs/tags/0.01 add dir1/file2\0Florian Ragwitz <rafl\@debian.org> 1173210275 +0100";
+#my $revline="a92fb1c9282f7319099ce7f783c8be7d5360f6e3\0refs/heads/model-cleanup\0Zachary Stevens <zts\@cryptocracy.com> 1277601094 +0100";
+my $instance = Gitalist::Git::Tag->new($revline);
+isa_ok($instance, 'Gitalist::Git::Tag');
+
+# Create an instance, passing last_change as a DateTime
+use DateTime;
+my $timespec = [1173210275, '+0100'];
+my $dt = DateTime->from_epoch(
+ epoch => @$timespec[0],
+ time_zone => @$timespec[1],
+);
+my $head = Gitalist::Git::Tag->new(
+ sha1 => '36c6c6708b8360d7023e8a1649c45bcf9b3bd818',
+ name => '0.01',
+ type => 'commit',
+ committer => 'Florian Ragwitz <rafl@debian.org>',
+ last_change => $dt,
+);
+isa_ok($head, 'Gitalist::Git::Tag');
@@ -1,6 +1,6 @@
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -1,3 +1,10 @@
+use FindBin qw/$Bin/;
+BEGIN {
+ my $env = "$FindBin::Bin/../../script/env";
+ if (-r $env) {
+ do $env or die $@;
+ }
+}
use Test::NoTabs;
all_perl_files_ok(qw(t lib));
@@ -1,8 +1,16 @@
#!/usr/bin/env perl
+use FindBin qw/$Bin/;
+BEGIN {
+ my $env = "$FindBin::Bin/../../script/env";
+ if (-r $env) {
+ do $env or die $@;
+ }
+}
+
use strict;
use warnings;
use Test::More;
use Test::Pod 1.14;
-all_pod_files_ok();
+all_pod_files_ok( all_pod_files('lib') );
@@ -1,14 +1,21 @@
-#!/usr/bin/env perl
+use FindBin qw/$Bin/;
+BEGIN {
+ my $env = "$FindBin::Bin/../../script/env";
+ if (-r $env) {
+ do $env or die $@;
+ }
+}
+
use strict;
use warnings;
use Test::More;
use Test::Pod::Coverage 1.04;
-all_pod_coverage_ok({
+pod_coverage_ok($_, {
also_private => [qw/
BUILD
BUILDARGS
build_per_context_instance
/],
-});
+}) for all_modules('lib');
@@ -0,0 +1 @@
+ref: refs/heads/master
@@ -0,0 +1,7 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = true
+ sharedrepository = 1
+[receive]
+ denyNonFastforwards = true
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit. The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "applypatch-msg".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/commit-msg" &&
+ exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
+:
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message.
+# Called by git-commit with one argument, the name of the file
+# that has the commit message. The hook should exit with non-zero
+# status after issuing an appropriate message if it wants to stop the
+# commit. The hook is allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "commit-msg".
+
+# Uncomment the below to add a Signed-off-by line to the message.
+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
+# hook is more suited to it.
+#
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+
+# This example catches duplicate Signed-off-by lines.
+
+test "" = "$(grep '^Signed-off-by: ' "$1" |
+ sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
+ echo >&2 Duplicate Signed-off-by lines.
+ exit 1
+}
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script that is called after a successful
+# commit is made.
+#
+# To enable this hook, rename this file to "post-commit".
+
+: Nothing
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script for the "post-receive" event.
+#
+# The "post-receive" script is run after receive-pack has accepted a pack
+# and the repository has been updated. It is passed arguments in through
+# stdin in the form
+# <oldrev> <newrev> <refname>
+# For example:
+# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
+#
+# see contrib/hooks/ for a sample, or uncomment the next line and
+# rename the file to "post-receive".
+
+#. /usr/share/doc/git-core/contrib/hooks/post-receive-email
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script to prepare a packed repository for use over
+# dumb transports.
+#
+# To enable this hook, rename this file to "post-update".
+
+exec git-update-server-info
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-applypatch".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/pre-commit" &&
+ exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
+:
@@ -0,0 +1,46 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by git-commit with no arguments. The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git-rev-parse --verify HEAD >/dev/null 2>&1
+then
+ against=HEAD
+else
+ # Initial commit: diff against an empty tree object
+ against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+# If you want to allow non-ascii filenames set this variable to true.
+allownonascii=$(git config hooks.allownonascii)
+
+# Cross platform projects tend to avoid non-ascii filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+ # Note that the use of brackets around a tr range is ok here, (it's
+ # even required, for portability to Solaris 10's /usr/bin/tr), since
+ # the square bracket bytes happen to fall in the designated range.
+ test "$(git diff --cached --name-only --diff-filter=A -z $against |
+ LC_ALL=C tr -d '[ -~]\0')"
+then
+ echo "Error: Attempt to add a non-ascii file name."
+ echo
+ echo "This can cause problems if you want to work"
+ echo "with people on other platforms."
+ echo
+ echo "To be portable it is advisable to rename the file ..."
+ echo
+ echo "If you know what you are doing you can disable this"
+ echo "check using:"
+ echo
+ echo " git config hooks.allownonascii true"
+ echo
+ exit 1
+fi
+
+exec git diff-index --check --cached $against --
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2006, 2008 Junio C Hamano
+#
+# The "pre-rebase" hook is run just before "git-rebase" starts doing
+# its job, and can prevent the command from running by exiting with
+# non-zero status.
+#
+# The hook is called with the following parameters:
+#
+# $1 -- the upstream the series was forked from.
+# $2 -- the branch being rebased (or empty when rebasing the current branch).
+#
+# This sample shows how to prevent topic branches that are already
+# merged to 'next' branch from getting rebased, because allowing it
+# would result in rebasing already published history.
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+ topic="refs/heads/$2"
+else
+ topic=`git symbolic-ref HEAD` ||
+ exit 0 ;# we do not interrupt rebasing detached HEAD
+fi
+
+case "$topic" in
+refs/heads/??/*)
+ ;;
+*)
+ exit 0 ;# we do not interrupt others.
+ ;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master. Is it OK to rebase it?
+
+# Does the topic really exist?
+git show-ref -q "$topic" || {
+ echo >&2 "No such branch $topic"
+ exit 1
+}
+
+# Is topic fully merged to master?
+not_in_master=`git-rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+ echo >&2 "$topic is fully merged to master; better remove it."
+ exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next? If so you should not be rebasing it.
+only_next_1=`git-rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git-rev-list ^master ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+ not_in_topic=`git-rev-list "^$topic" master`
+ if test -z "$not_in_topic"
+ then
+ echo >&2 "$topic is already up-to-date with master"
+ exit 1 ;# we could allow it, but there is no point.
+ else
+ exit 0
+ fi
+else
+ not_in_next=`git-rev-list --pretty=oneline ^${publish} "$topic"`
+ perl -e '
+ my $topic = $ARGV[0];
+ my $msg = "* $topic has commits already merged to public branch:\n";
+ my (%not_in_next) = map {
+ /^([0-9a-f]+) /;
+ ($1 => 1);
+ } split(/\n/, $ARGV[1]);
+ for my $elem (map {
+ /^([0-9a-f]+) (.*)$/;
+ [$1 => $2];
+ } split(/\n/, $ARGV[2])) {
+ if (!exists $not_in_next{$elem->[0]}) {
+ if ($msg) {
+ print STDERR $msg;
+ undef $msg;
+ }
+ print STDERR " $elem->[1]\n";
+ }
+ }
+ ' "$topic" "$not_in_next" "$not_in_master"
+ exit 1
+fi
+
+exit 0
+
+################################################################
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+ merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+ it is deleted. If you need to build on top of it to correct
+ earlier mistakes, a new topic branch is created by forking at
+ the tip of the "master". This is not strictly necessary, but
+ it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+ branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next". Young
+ topic branches can have stupid mistakes you would rather
+ clean up before publishing, and things that have not been
+ merged into other branches can be easily rebased without
+ affecting other people. But once it is published, you would
+ not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+ Then you can delete it. More importantly, you should not
+ build on top of it -- other people may already want to
+ change things related to the topic as patches against your
+ "master", so if you need further changes, it is better to
+ fork the topic (perhaps with the same name) afresh from the
+ tip of "master".
+
+Let's look at this example:
+
+ o---o---o---o---o---o---o---o---o---o "next"
+ / / / /
+ / a---a---b A / /
+ / / / /
+ / / c---c---c---c B /
+ / / / \ /
+ / / / b---b C \ /
+ / / / / \ /
+ ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished. It has been fully merged up to "master" and "next",
+ and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+ git-rev-list ^master ^topic next
+ git-rev-list ^master next
+
+ if these match, topic has not merged in next at all.
+
+To compute (2):
+
+ git-rev-list master..topic
+
+ if this is empty, it is fully merged to "master".
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# An example hook script to prepare the commit log message.
+# Called by git-commit with the name of the file that has the
+# commit message, followed by the description of the commit
+# message's source. The hook's purpose is to edit the commit
+# message file. If the hook fails with a non-zero status,
+# the commit is aborted.
+#
+# To enable this hook, rename this file to "prepare-commit-msg".
+
+# This hook includes three examples. The first comments out the
+# "Conflicts:" part of a merge commit.
+#
+# The second includes the output of "git diff --name-status -r"
+# into the message, just before the "git status" output. It is
+# commented because it doesn't cope with --amend or with squashed
+# commits.
+#
+# The third example adds a Signed-off-by line to the message, that can
+# still be edited. This is rarely a good idea.
+
+case "$2,$3" in
+ merge,)
+ perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+
+# ,|template,)
+# perl -i.bak -pe '
+# print "\n" . `git diff --cached --name-status -r`
+# if /^#/ && $first++ == 0' "$1" ;;
+
+ *) ;;
+esac
+
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
@@ -0,0 +1,128 @@
+#!/bin/sh
+#
+# An example hook script to blocks unannotated tags from entering.
+# Called by git-receive-pack with arguments: refname sha1-old sha1-new
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# hooks.allowunannotated
+# This boolean sets whether unannotated tags will be allowed into the
+# repository. By default they won't be.
+# hooks.allowdeletetag
+# This boolean sets whether deleting tags will be allowed in the
+# repository. By default they won't be.
+# hooks.allowmodifytag
+# This boolean sets whether a tag may be modified after creation. By default
+# it won't be.
+# hooks.allowdeletebranch
+# This boolean sets whether deleting branches will be allowed in the
+# repository. By default they won't be.
+# hooks.denycreatebranch
+# This boolean sets whether remotely creating branches will be denied
+# in the repository. By default this is allowed.
+#
+
+# --- Command line
+refname="$1"
+oldrev="$2"
+newrev="$3"
+
+# --- Safety check
+if [ -z "$GIT_DIR" ]; then
+ echo "Don't run this script from the command line." >&2
+ echo " (if you want, you could supply GIT_DIR then run" >&2
+ echo " $0 <ref> <oldrev> <newrev>)" >&2
+ exit 1
+fi
+
+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
+ echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
+ exit 1
+fi
+
+# --- Config
+allowunannotated=$(git config --bool hooks.allowunannotated)
+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
+denycreatebranch=$(git config --bool hooks.denycreatebranch)
+allowdeletetag=$(git config --bool hooks.allowdeletetag)
+allowmodifytag=$(git config --bool hooks.allowmodifytag)
+
+# check for no description
+projectdesc=$(sed -e '1q' "$GIT_DIR/description")
+case "$projectdesc" in
+"Unnamed repository"* | "")
+ echo "*** Project description file hasn't been set" >&2
+ exit 1
+ ;;
+esac
+
+# --- Check types
+# if $newrev is 0000...0000, it's a commit to delete a ref.
+zero="0000000000000000000000000000000000000000"
+if [ "$newrev" = "$zero" ]; then
+ newrev_type=delete
+else
+ newrev_type=$(git-cat-file -t $newrev)
+fi
+
+case "$refname","$newrev_type" in
+ refs/tags/*,commit)
+ # un-annotated tag
+ short_refname=${refname##refs/tags/}
+ if [ "$allowunannotated" != "true" ]; then
+ echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
+ echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
+ exit 1
+ fi
+ ;;
+ refs/tags/*,delete)
+ # delete tag
+ if [ "$allowdeletetag" != "true" ]; then
+ echo "*** Deleting a tag is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ refs/tags/*,tag)
+ # annotated tag
+ if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
+ then
+ echo "*** Tag '$refname' already exists." >&2
+ echo "*** Modifying a tag is not allowed in this repository." >&2
+ exit 1
+ fi
+ ;;
+ refs/heads/*,commit)
+ # branch
+ if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
+ echo "*** Creating a branch is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ refs/heads/*,delete)
+ # delete branch
+ if [ "$allowdeletebranch" != "true" ]; then
+ echo "*** Deleting a branch is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ refs/remotes/*,commit)
+ # tracking branch
+ ;;
+ refs/remotes/*,delete)
+ # delete tracking branch
+ if [ "$allowdeletebranch" != "true" ]; then
+ echo "*** Deleting a tracking branch is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ *)
+ # Anything else (is there anything else?)
+ echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
+ exit 1
+ ;;
+esac
+
+# --- Finished
+exit 0
@@ -0,0 +1,6 @@
+# git-ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
@@ -0,0 +1 @@
+ref: refs/heads/master
@@ -0,0 +1,7 @@
+[core]
+ repositoryformatversion = 0
+ filemode = true
+ bare = true
+ sharedrepository = 1
+[receive]
+ denyNonFastforwards = true
@@ -0,0 +1 @@
+Unnamed repository; edit this file 'description' to name the repository.
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit. The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "applypatch-msg".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/commit-msg" &&
+ exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
+:
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# An example hook script to check the commit log message.
+# Called by git-commit with one argument, the name of the file
+# that has the commit message. The hook should exit with non-zero
+# status after issuing an appropriate message if it wants to stop the
+# commit. The hook is allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "commit-msg".
+
+# Uncomment the below to add a Signed-off-by line to the message.
+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
+# hook is more suited to it.
+#
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+
+# This example catches duplicate Signed-off-by lines.
+
+test "" = "$(grep '^Signed-off-by: ' "$1" |
+ sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
+ echo >&2 Duplicate Signed-off-by lines.
+ exit 1
+}
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script that is called after a successful
+# commit is made.
+#
+# To enable this hook, rename this file to "post-commit".
+
+: Nothing
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# An example hook script for the "post-receive" event.
+#
+# The "post-receive" script is run after receive-pack has accepted a pack
+# and the repository has been updated. It is passed arguments in through
+# stdin in the form
+# <oldrev> <newrev> <refname>
+# For example:
+# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
+#
+# see contrib/hooks/ for a sample, or uncomment the next line and
+# rename the file to "post-receive".
+
+#. /usr/share/doc/git-core/contrib/hooks/post-receive-email
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# An example hook script to prepare a packed repository for use over
+# dumb transports.
+#
+# To enable this hook, rename this file to "post-update".
+
+exec git-update-server-info
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-applypatch".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/pre-commit" &&
+ exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
+:
@@ -0,0 +1,46 @@
+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by git-commit with no arguments. The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git-rev-parse --verify HEAD >/dev/null 2>&1
+then
+ against=HEAD
+else
+ # Initial commit: diff against an empty tree object
+ against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+# If you want to allow non-ascii filenames set this variable to true.
+allownonascii=$(git config hooks.allownonascii)
+
+# Cross platform projects tend to avoid non-ascii filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+ # Note that the use of brackets around a tr range is ok here, (it's
+ # even required, for portability to Solaris 10's /usr/bin/tr), since
+ # the square bracket bytes happen to fall in the designated range.
+ test "$(git diff --cached --name-only --diff-filter=A -z $against |
+ LC_ALL=C tr -d '[ -~]\0')"
+then
+ echo "Error: Attempt to add a non-ascii file name."
+ echo
+ echo "This can cause problems if you want to work"
+ echo "with people on other platforms."
+ echo
+ echo "To be portable it is advisable to rename the file ..."
+ echo
+ echo "If you know what you are doing you can disable this"
+ echo "check using:"
+ echo
+ echo " git config hooks.allownonascii true"
+ echo
+ exit 1
+fi
+
+exec git diff-index --check --cached $against --
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2006, 2008 Junio C Hamano
+#
+# The "pre-rebase" hook is run just before "git-rebase" starts doing
+# its job, and can prevent the command from running by exiting with
+# non-zero status.
+#
+# The hook is called with the following parameters:
+#
+# $1 -- the upstream the series was forked from.
+# $2 -- the branch being rebased (or empty when rebasing the current branch).
+#
+# This sample shows how to prevent topic branches that are already
+# merged to 'next' branch from getting rebased, because allowing it
+# would result in rebasing already published history.
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+ topic="refs/heads/$2"
+else
+ topic=`git symbolic-ref HEAD` ||
+ exit 0 ;# we do not interrupt rebasing detached HEAD
+fi
+
+case "$topic" in
+refs/heads/??/*)
+ ;;
+*)
+ exit 0 ;# we do not interrupt others.
+ ;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master. Is it OK to rebase it?
+
+# Does the topic really exist?
+git show-ref -q "$topic" || {
+ echo >&2 "No such branch $topic"
+ exit 1
+}
+
+# Is topic fully merged to master?
+not_in_master=`git-rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+ echo >&2 "$topic is fully merged to master; better remove it."
+ exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next? If so you should not be rebasing it.
+only_next_1=`git-rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git-rev-list ^master ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+ not_in_topic=`git-rev-list "^$topic" master`
+ if test -z "$not_in_topic"
+ then
+ echo >&2 "$topic is already up-to-date with master"
+ exit 1 ;# we could allow it, but there is no point.
+ else
+ exit 0
+ fi
+else
+ not_in_next=`git-rev-list --pretty=oneline ^${publish} "$topic"`
+ perl -e '
+ my $topic = $ARGV[0];
+ my $msg = "* $topic has commits already merged to public branch:\n";
+ my (%not_in_next) = map {
+ /^([0-9a-f]+) /;
+ ($1 => 1);
+ } split(/\n/, $ARGV[1]);
+ for my $elem (map {
+ /^([0-9a-f]+) (.*)$/;
+ [$1 => $2];
+ } split(/\n/, $ARGV[2])) {
+ if (!exists $not_in_next{$elem->[0]}) {
+ if ($msg) {
+ print STDERR $msg;
+ undef $msg;
+ }
+ print STDERR " $elem->[1]\n";
+ }
+ }
+ ' "$topic" "$not_in_next" "$not_in_master"
+ exit 1
+fi
+
+exit 0
+
+################################################################
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+ merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+ it is deleted. If you need to build on top of it to correct
+ earlier mistakes, a new topic branch is created by forking at
+ the tip of the "master". This is not strictly necessary, but
+ it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+ branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next". Young
+ topic branches can have stupid mistakes you would rather
+ clean up before publishing, and things that have not been
+ merged into other branches can be easily rebased without
+ affecting other people. But once it is published, you would
+ not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+ Then you can delete it. More importantly, you should not
+ build on top of it -- other people may already want to
+ change things related to the topic as patches against your
+ "master", so if you need further changes, it is better to
+ fork the topic (perhaps with the same name) afresh from the
+ tip of "master".
+
+Let's look at this example:
+
+ o---o---o---o---o---o---o---o---o---o "next"
+ / / / /
+ / a---a---b A / /
+ / / / /
+ / / c---c---c---c B /
+ / / / \ /
+ / / / b---b C \ /
+ / / / / \ /
+ ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished. It has been fully merged up to "master" and "next",
+ and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+ git-rev-list ^master ^topic next
+ git-rev-list ^master next
+
+ if these match, topic has not merged in next at all.
+
+To compute (2):
+
+ git-rev-list master..topic
+
+ if this is empty, it is fully merged to "master".
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# An example hook script to prepare the commit log message.
+# Called by git-commit with the name of the file that has the
+# commit message, followed by the description of the commit
+# message's source. The hook's purpose is to edit the commit
+# message file. If the hook fails with a non-zero status,
+# the commit is aborted.
+#
+# To enable this hook, rename this file to "prepare-commit-msg".
+
+# This hook includes three examples. The first comments out the
+# "Conflicts:" part of a merge commit.
+#
+# The second includes the output of "git diff --name-status -r"
+# into the message, just before the "git status" output. It is
+# commented because it doesn't cope with --amend or with squashed
+# commits.
+#
+# The third example adds a Signed-off-by line to the message, that can
+# still be edited. This is rarely a good idea.
+
+case "$2,$3" in
+ merge,)
+ perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+
+# ,|template,)
+# perl -i.bak -pe '
+# print "\n" . `git diff --cached --name-status -r`
+# if /^#/ && $first++ == 0' "$1" ;;
+
+ *) ;;
+esac
+
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
@@ -0,0 +1,128 @@
+#!/bin/sh
+#
+# An example hook script to blocks unannotated tags from entering.
+# Called by git-receive-pack with arguments: refname sha1-old sha1-new
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# hooks.allowunannotated
+# This boolean sets whether unannotated tags will be allowed into the
+# repository. By default they won't be.
+# hooks.allowdeletetag
+# This boolean sets whether deleting tags will be allowed in the
+# repository. By default they won't be.
+# hooks.allowmodifytag
+# This boolean sets whether a tag may be modified after creation. By default
+# it won't be.
+# hooks.allowdeletebranch
+# This boolean sets whether deleting branches will be allowed in the
+# repository. By default they won't be.
+# hooks.denycreatebranch
+# This boolean sets whether remotely creating branches will be denied
+# in the repository. By default this is allowed.
+#
+
+# --- Command line
+refname="$1"
+oldrev="$2"
+newrev="$3"
+
+# --- Safety check
+if [ -z "$GIT_DIR" ]; then
+ echo "Don't run this script from the command line." >&2
+ echo " (if you want, you could supply GIT_DIR then run" >&2
+ echo " $0 <ref> <oldrev> <newrev>)" >&2
+ exit 1
+fi
+
+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
+ echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
+ exit 1
+fi
+
+# --- Config
+allowunannotated=$(git config --bool hooks.allowunannotated)
+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
+denycreatebranch=$(git config --bool hooks.denycreatebranch)
+allowdeletetag=$(git config --bool hooks.allowdeletetag)
+allowmodifytag=$(git config --bool hooks.allowmodifytag)
+
+# check for no description
+projectdesc=$(sed -e '1q' "$GIT_DIR/description")
+case "$projectdesc" in
+"Unnamed repository"* | "")
+ echo "*** Project description file hasn't been set" >&2
+ exit 1
+ ;;
+esac
+
+# --- Check types
+# if $newrev is 0000...0000, it's a commit to delete a ref.
+zero="0000000000000000000000000000000000000000"
+if [ "$newrev" = "$zero" ]; then
+ newrev_type=delete
+else
+ newrev_type=$(git-cat-file -t $newrev)
+fi
+
+case "$refname","$newrev_type" in
+ refs/tags/*,commit)
+ # un-annotated tag
+ short_refname=${refname##refs/tags/}
+ if [ "$allowunannotated" != "true" ]; then
+ echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
+ echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
+ exit 1
+ fi
+ ;;
+ refs/tags/*,delete)
+ # delete tag
+ if [ "$allowdeletetag" != "true" ]; then
+ echo "*** Deleting a tag is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ refs/tags/*,tag)
+ # annotated tag
+ if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
+ then
+ echo "*** Tag '$refname' already exists." >&2
+ echo "*** Modifying a tag is not allowed in this repository." >&2
+ exit 1
+ fi
+ ;;
+ refs/heads/*,commit)
+ # branch
+ if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
+ echo "*** Creating a branch is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ refs/heads/*,delete)
+ # delete branch
+ if [ "$allowdeletebranch" != "true" ]; then
+ echo "*** Deleting a branch is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ refs/remotes/*,commit)
+ # tracking branch
+ ;;
+ refs/remotes/*,delete)
+ # delete tracking branch
+ if [ "$allowdeletebranch" != "true" ]; then
+ echo "*** Deleting a tracking branch is not allowed in this repository" >&2
+ exit 1
+ fi
+ ;;
+ *)
+ # Anything else (is there anything else?)
+ echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
+ exit 1
+ ;;
+esac
+
+# --- Finished
+exit 0
@@ -0,0 +1,6 @@
+# git-ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/var/tmp/source/BROQ/Gitalist-0.002007/Gitalist-0.002007/t/lib/repositories/recursive/nothinginhere/emptyfile b/var/tmp/source/BROQ/Gitalist-0.002007/Gitalist-0.002007/t/lib/repositories/recursive/nothinginhere/emptyfile
new file mode 100644
index 00000000..e69de29b
@@ -1,6 +1,6 @@
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -95,7 +95,7 @@ throws_ok { Gitalist::Model::CollectionOfRepos->COMPONENT($ctx_gen->(), { repos
{
my $i = test_with_config({ repo_dir => "$FindBin::Bin/lib/repositories"});
- is scalar($i->repositories->flatten), 3, 'Found 3 repos';
+ is scalar($i->repositories->flatten), 5, 'Found 5 repos';
}
{
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -1,7 +1,7 @@
#!/usr/bin/env perl
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -1,6 +1,6 @@
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}
@@ -1,6 +1,6 @@
use FindBin qw/$Bin/;
BEGIN {
- my $env = "$FindBin::Bin/script/env";
+ my $env = "$FindBin::Bin/../script/env";
if (-r $env) {
do $env or die $@;
}